Здравствуйте, ·, Вы писали:
>>>Мой поинт в том, что моки это не про то как пишется код, функциями, классами или чёртом лысым, а про внешние зависимости. И никакой правильный дизайн от них не избавляет, т.к. зависимости диктуются требованиями, а не дизайном. Если у тебя есть субд, будут моки, как ни дизайни. Ну или если у тебя хоумпейдж, а там что угодно делай, не важно.
P>>Зависимости — требованиями, а способ их протаскивания — дизайном. Соответственно, моки это обрезание тех зависимостей, которые вы же сами затолкали куда поглубже, да еще неглядя.
·>Пофиг. Зависимости надо мокать. Точка. В этом твоём потоке речи единственный факт: "моки это обрезание зависимостей". А остальное — бессмысленные фантазии.
Вы раз за разом повторяете что верите в моки. Зачем? Это ж не аргумент, зато выглядит смешно.
Зависимости нужно учитывать в тестах
1. классический — убираем их целиком, что есть особенность дизайна
2. моки — собственно, пишем моки, код можно писать как попало
В первом случае у нас приложение будет похоже вот на такой слоеный пирог, где 0 это точка отсчета
3 - контроллер - линейный код
2 - use case - именно здесь вызывается DB, этот код делаем максимально линейным
1 - BL - чистая
0 - модель - чистая
Второй вариант, ваш любимый
3 - контроллер
1 - BL грязная, DTO и есть наша модель, вызывает DB или напрямую DAL, или через ваши репозитории, итд, что требует инжекции
0 - DB
P>>Серьёзная логика. А еще Фаулер показал олдскульный жээс и вдвое большее количество кода, чем нужно, даже с его подходом.
·>Серьёзная, да. Ни показать своё решение, ни улучшить чужое ты не можешь.
Я вам уже много раз предлагал посмотреть clean architecture, глянуть, как там работают с бд. Вы хотите что бы я все это пересказал вам здесь?
P>>А так — в контроллере останется ровно то, что требуется для функциональных требований. А вот всё остальное вам придется распихивать, например, в ту же очередь. И вот такие изменения ломают и ваши моки, и тесты на них.
·>Изменения ломают моки только если они изменяют функциональность.
У вас функциональность это весьма расплывчатое понятие. Туда разве что каменты не входят. Или входят?
·>Раньше после нажатия на кнопочку "создать" появлялась кнопочка "поменять" и она работала, но ты сделал очень такое "нефункциональное" изменение, и теперь эту кнопочку можно нажимать только через пять минут, а до этого какие-то невнятные ошибки. Молодец, чё, а юзерам всегда можно сказать "have you tried to turning it on and off again?". Зато тесты не сломались!
Кто вам такое сказал?
Вам нужно редактировать не все отношения юзера, а только user-facing. Все остальное вы вас не заботит.
P>>Вы наверное подумали, но забыли написать. Поиск по треду никаких пояснений, как вы используете конформационные тесты, не дал.
·>ТутАвтор: ·
Дата: 05.02.24
.
Читаем вместе:
нами был напилен набор интеграционных тестов, которые гонялись в каждом acceptance. И мы чаще всего ловили там не глюки нашего софта (которые были отловлены юнит-тестами), а регрессию со стороны Microsoft .
S>Было всего несколько случаев, когда поведение API было не таким, как мы ожидали, и это не было признано багом.
Это называется conformance tests.
То есть, здесь вы назвали интеграционные тесты conformance.
Если вы все еще не согласны — объясните внятно
1 кто пишет эти conformance tests
2 какой код должен выполниться, что бы пройти эти тесты
Ощущение, что вы путаете вид тестов и уровень. Уровень — сколько строк, компонентов, ид задействуется при тесте — юниты, и интеграционные, куда относятся компоненты, функциональные, приложение, система.
Вид — контрактные, конформанс, пенетрейшн, перформанс, e2e, на моках, без моков, приемочные, итд
Конформанс — интеграционные. По определению.
P>>Ровно так же поступают и с компилятором — запускают и прогоняют 100500 примеров кода по спецификации.
·>Аналогом твоего решения будет тестировать, что функция createUser компилируется в конкретный ассемблерный код.
Незачем — у нас трансляция json -> sql.
P>>Фактически, вы пишете ни больше, ни меньше, а небольшой компилятор из json в sql. Только у вас нет этих самых эталонов — под вашу бд и придумки их никто не заготовил.
·>Вот я и не понимаю каким образом ты собираешься проверять, что этот самый sql выдаёт хоть какие-то правильные данные, а не > кто-то перепутал с < на какой-то комбинации входных данных. И не один раз "проверить" (а на самом деле скопипастить из реализации в тест) в процессе набора кода, но и для регрессии.
Я ж вам объяснил раз пять
1. находим паттерн и проверяем его
2. пишем маппер вокруг паттерна и проверяем маппер
Нам нужны и 1 и 2.
Если 1 без 2, то всё в порядке — запрос работает на тестовых данных, но в проде вгружает всю БД в память, потому что подстановки параметров работают только для тестов
Если 2 без 1, то хер его знает, что там делается вообще
А если и 1, и 2, то
1. благодаря правильному паттерну у нас рабочая схема
2. благодаря 2 у нас правильные подстановки в этот паттерн
P>>1. получили рабочий паттерн
P>>2. строим маппер вокруг этого паттерна
·>Что за маппер вокруг паттерна? У тебя маппер был частью паттерна как transformations: out:[fn1]
А название таблицы само выросло, да? Подстановка параметров, условий, названий колонок, таблиц, подстановка fn1 и fn2 тоже само? Это именно работа маппера — по json получить рабочий запрос, который будет соответствовать нашим ожиданиям
Это нужно на тот случай, если некто решит сделать "быстрый маленький фикс" после того, как вы уволитесь и контролировать код перестанете
·>Этих паттернов будут на каждый сценарий/юнит-тест. Т.е. кол-во ручного тестирования и и-тестов получается такое же. Следовательно смысла от таких тестов ноль.
В вашей схеме ровно так же. Только вы построение запроса никак не контролируете.
·>Этих паттерны не будут покрываться интеграцией, а значит опечатки в тексте sql скопипасченные из реализации в тест и регрессии будут обнаруживаться только на проде юзерами.
Вы в адеквате? Я ж сказал — интеграционные тесты никуда не деваются. А вы читаете чтото своё.
P>>п2 — построение запроса тестируется как все мапперы, без исключения
P>>Без п2 вы спокойно напоретесь на кейс с уязвимостью, или поломкой на энкодинге данных, или с (не)подтягиванием данных из (не)тех таблиц
·>У тебя что-то очень не то с дизайном, что у тебя какие-то технические детали с энкодингом данных намешаны с бизнес-логикой реализации сценариев.
Причин сломать построение запроса при валидном паттерне — огромной количество — например, пупутать названия таблиц, колонок, приоритет операторов итд и тди итд.
P>>Подробнее — кто и где выдаст вам конф-тест, что запросы смогут внятн что работать с такими вещами — email в таблице users это сам емейл строкой, а email в таблице reply будет mailto:<email>, а в customer он будет в колонке типа json с названием поля 'details' который есть список имя-значение.
·>Я не понял что ты тут спрашиваешь. Какой ещё емейл?
Я вам пример привел, что построение запроса по json должно учитывать схему бд. Вот это и проверяем. В каких то случаях невалидный запрос может выдавать данные очень похожие на правильные, и это вполне себе реальная проблема.
·>Т.е. правила енкодинга определяются для типов данных, например, в строках надо non-ascii енкодить. А бизнес-логика работает со значениниями. И все значения firstname/lastname/&c это строки, енкодинг которых уже покрыт. И не надо отдельно проверять что каждое поле правильно енкодится.
Кто будет проверять, что email может энкодиться десятком способов в вашей бд? Подробнее. Ну вот досталось вам от предшественника такое. Ваши действия?
·>А как ты его проверишь-то?
Примерно так же, как и вы. Только проверка паттерна мало что гарантирует. См выше про загрузку всей бд в память. Паттерн корректный, ошибочка при рендеринге некоторых комбинаций фильтров.
P>>а не конечный запрос, как у вас. Потому мне в будущее заглядывать не надо, цитирую себя "тестом бд минимально заполненой под задачу"
·>Ты уже запамятовал? Ты показывал код, где у тебя в паттерне был конечный запрос.
Это выхлоп билдера запросов. не рукописный sql, а результат билдера. Соответсвенно, мы можем проверить работу сложного маппера json -> sql, при чем гораздо плотнее, чем вашими косвенными тестами.
Например, я могу просто заложиться на юнит-тест, и потребовать двойную фильтрацию — первая по периоду, вторая — по параметрам, или вставить limit x, итд итд
И у меня точно не будет кейса "вгружаем всю бд в память".
Даже если в интеграционных тестах у меня не будет 100_000_000_000 записей, ничего страшного — запрос всё равно будет с безопасной структурой.
P>>Смотрите внимательно — объяснение ниже я вам приводил уже около десятка раз
·>Это всё вода. Ты показал конкретный код, я указал в этом конкретном коде конкретную проблему. Ты теперь заявляешь что что-то мне объяснял. Без кода объяснения идут в топку. Я никогда не просил ничего объяснять, я просил показать код.
Правильнее сказать, что вам непонятно, почему ваш подход не будет работать, а мой — будет.
Ваш никак не учитывает data complexity. Мой — именно на этом и строится, см пример выше про 100_000_000_000 записей.
Т.е. мне нужно
1. быть в курсе про возможную проблему с загрузкой конской таблицы из за ошибок в построении фильтров
2. найти решение
3. зафиксировать теми тестами, которые вам кажутся лишними
А вот вы так и не показали тест "никогда не будем загружать всю бд в память". Вы показали другой совсем другой тест — загрузим 1, если только что записали 1.
·>Мы говорим о тестах. В коде теста есть паттерн который туда кто-то как-то напечатал, хз как. Ты так и не рассказал как убедиться что этот самый код корректный. "погонять запрос вручную в sql-консоли" — это был твой лучший ответ.
Читаем вместе:
п1 — паттерн тестируется на бд, далее — интеграционными тестами
Сколько бы я ни писал про интеграционные тесты, вам мерещится "погонять вручную"
Это какая то особенность вашего восприятия
·>Как они видны-то? Где что красненьким подчеркнётся?
См выше, "никогда не будем загружать всю бд в память" — для этого кейса у вас ни одного теста, а у меня хоть какие то.