Здравствуйте, Pauel, Вы писали:
P>·>Действительно. Какой смысл искать верное решение задачи, если в предыдущем были ошибки. Отличная логика!
P>Вы пока ошибок не показали. Основная ваша придирка в том, что структурная эквивалентность не нужна, хрупкая, итд — при этом альтернативы такому решению у вас нет.
Это и есть ошибка. Плюс показал потенциальные ошибки например с дефолтным значением vs null. Альтернативу тоже показал. Просто ты проигнорировал.
P>>>Очень просто — редактироавние после записи нужно для конкретных целей, например — что бы администратор мог подправить свойства только что созданного юзера, а не ждать пять минут.
P>·>Это вроде очевидное требование. Необходимость пользователям ждать по пять минут перед тем как нажать кнопочку — должно быть серьёзно обоснованно и обговорено с заказчиком. Как ты это вообще представляешь?
P>Вы снова с колокольни? Ничего ждать не надо — в том то и особенность. И всё работает. Потому как данные по пользователю делятся на две большие части — те, что нужны сейчас, и те, что просто нужны.
P>Вот например — под нового сотрудника аккаунт создаётся заранее. Здесь заботиться о том, что бы всё-всё-всё(и все гуиды редактировали руками, ага) было доступно к редактированию через 50мс — требование неадекватное.
P>А вот изменение имени пользователя спустя секунду после создания — очень даже адекватно.
Ты путаешься в показаниях. Ты сам-то адекватен? Откуда взялось "50мс"??! Ты тут сказал, что синхронное сохранение внезапно заменил на асинхронное и у тебя возникли проблемы с тем, что теперь другой метод можно позвать только через 5 минут. Хуже того, асинхронное вообще не обещает, что оно таки когда-либо произойдёт, а не выпадет какая-нибудь ошибка, которую теперь надо как-то отображать.
P>>>Если ваш бизнес аналиитк затребовал вообще всё такое — то вы приплыли.
P>·>Я не в курсе что такое "паблик кей спейса юзера".
P>public ssl key — ничего военного. Пересоздавать этот кей спустя секунду после создания занятие абсолютно бессмысленное. А вас послушать, так окажется что любые данные ассоциированые с пользователем могут меняться сразу же, включая гуиды ссылок на любую глубину связности.
Я не знаю что это и какое это всё имеет отношение к обсуждаемому.
P>·>Ты ни разу не ответил прямо на этот вопрос.
P>Цитирую себя N+1й и N+2q разы
P>P>п1 — паттерн тестируется на бд, далее — интеграционными тестами
P>...
P>1. рабочий паттерн запроса — это проверяется сначала руками, а потом тестом против бд минимально заполненой под задачу
P>Я вот почему то уверен, что несмотря на эти цитаты вы еще месяц или два будете мне доказывать, что я тестирую только юнит-тестами.
Ты пишешь бред. Я задаю вопрос, ты игнорируешь и снова повторяешь то же самое. Попробуем ещё раз:
Я читаю что написано. В цитате выше написано "тестируется" (само как-то?), потом стоит запятая и слово "далее" и про интеграционные тесты. Если эта твоя цитата не говорит что ты хочешь сказать, переформулируй, у меня очень плохо с телепатией.
P>>>Все код был даден, отмотайте и посмотрите, это всё та же структурная эквивалентность запроса к бд.
P>·>Мы рассмотрели этот пример, ты вроде даже признал, что там лажа.
P>Пример недостаточно информативный. А вот сам подход — проверять построение запроса — очень даже хороший.
Т.е. код не был даден. ЧТД. Куда отматывать-то?
P>·>что за основа? Запроса какого? sql?
P>Какого угодно. Если вам для запроса данных нужна цепочка джойнов или вложеный запрос — то это и есть паттерн.
Это ты цель со средством путаешь. Мне надо чтобы запрос выдавал результат который нужен по спеке. А что там — цепочка джойнов или чёрт лысый — абсолютно пофиг. Более того, если сегодня написали запрос с джойнами, а завтра, после разговора с dba его переписали на вложенный — то ни один тест упасть не должен.
P>А дальше наш билдер должен гарантировать, что для любых возможных параметров, а не только тех, что вы косвенно подкинули в тестах, запрос будет соответствовать заданному паттерно — цепочка джойнов, вложеный запрос, итд итд итд.
P>А так же надо учесть вещи вида "не делает то чего делать не должен".
Мы говорим о тестах. Как тебе тесты помогут что-то гарантировать? Причём тут тесты??!
P>>>трансформация — часть маппера, трансформируем json в нужный нам вид, на выходе — делаем обратное преобразование.,
P>·>Трансформация? Обратная? А что такое transformations? out:...? Это было частью pattern в твоём сниппете. Тут ты говоришь, что это часть маппера.
P>Путаница из за того, что есть паттерн запроса и паттерн в тесте это похожее, но разное
P>Вот смотрите
P>P>const request = Builder.createUser(...args);
P>expect(request).to.deep.eq({
P> in: fn1,
P> out: fn2,
P> sql: ' наш конкретный запрос ',
P> args: [ параметры для запроса]
P>})
P>
P>Все что передается в eq — паттерн для теста. А ' наш конкретный запрос' тут проверяем паттерн запроса к бд.
Здесь в коде это просто строка полного sql-запроса, которая сравнивается по equals. Я не понимаю почему ты это называешь паттерном, что в тут паттернится-то?
P>Синклер говорит, что эффективнее AST. Это конечно же так. Только пилить АСТ под частный случай я не вижу смысла, во первых. А во вторых, по похожей схеме мы можем проверять запросы любого вида http, rest, rpc, graphql, odata итд.
P>Например, для эластика у вас будет обычный http запрос.
P>Можно точно так же проверять запросы к ORM. Это решает проблемы с джигитам "я быстренько, там всё просто"
Ясно. Так я код с такими "паттернами" пишу как раз когда надо "я быстренько, там всё просто". В серьёзных ситуациях за такое надо бить по рукам.
P>>>Я вам продолжаю приводить тот же самый пример — фильтры, когда из за ошибки в построении запроса вгружается вся бд. Вы его усиленно игнорируете.
P>·>Я не игнорирую, я уже где-то месяц назад написал как его покрыть нормальным тестом. Это ты игнорируешь мои ответы.
P>Вы показали примитивные тесты вида "положили в таблицу, проверили, что нашли положенное". А как протестировать "не нашли неположенного" или "не начали вгружать вообще всё" — вы такого не показали.
Показал. Ещё раз разжую. Минимальный пример: Если мы в таблицу кладём "Vasya", то при поиске, например по шаблону по startsWith("Vas") — должны найти одну запись, а по startsWith("Vaz") — ноль. Второй тест как раз и ассертит, что твой этот фильтр не вгружает всё, а только то, что должно было заматчиться. Ещё раз. Одна запись в БД — это 2
1 вариантов результата, которые можно различить.
P>И то, и другое вашими примитивными тестами не решается.
Решается.
P>Частично можно решить на боевой бд или приравненой к ней, но только для тех данных что есть сейчас. Как это сделать для тех данных, что у нас будут через год — загадка.
Ты же уже сам привёл ответ на эту загадку: "все возможные кейсы что есть в бд прода, или
нам известно, что такие будут".
P>·>Он выполняется косвенно, через кучу слоёв: "когда у нас дошла очередь интеграционного тестирования, где (медленно!) тащатся реальные данные из реальной базы, выполняется (медленный!) UI workflow с навигацией от логина до этого отчёта, и т.п.".
P>·>Т.е. либо у тебя такие тесты будут гонятся неделями, либо ты сможешь покрыть только ничтожную долю комбинаций этих конкретных запросов.
P>·>В моём случае тесты выполняют только связку репо+бд и там можно гонять на порядки больше комбинаций.
P>Связка репо+бд называется интеграционный тест. Вы такими тестами собираетесь покрывать все комбинации
Совершенно похрен как оно называется. Я говорю конкретно что с чем тестируется и как.
P>И щас же будете рассказывать, что вы имели в виду чтото другое.
Я имел в виду ровно то, что написал. Если что-то неясно, перечитай.
P>Сколько бы вы комбинаций не всунули в репо+бд тесты — Data Complexity вам такими тестами не сбороть, ну никак.
P>Но вы продолжаете это пытаться.
P>Интеграционные нужны для проверки, что репо умеет работать с бд, а вовсе не для проверок комбинаций. Для проверок комбинаций есть другие методы, гораздо более эффективные.
Что значит "умеет работать"?
P>>>А раз покрыть все комбинации не получится, то незачем и пытаться — нужно переложить критические кейсы на другие методы.
P>·>Вот и неясно зачем вы пытаетесь это перекладывать на эти ваши странные бесполезные тесты, т.к. нужно другие методы использовать.
P>Вы только что "показали" — для проверок комбинций использовать интеграционный тест репо+бд
Почему нет-то?
P>>>И как вы протестируете, что у вас невозможна ситуация, что прод вгружает вообще всё?
P>·>Вы тоже не можете это _протестировать_. Просто ещё этого не поняли.
P>Могу. Например, для тестов которые тянут больше одной строки могу просто затребовать `LIMIT 10`.
Как?
P>>>·>Именно, для этого и нужны тесты репо+бд. А при наличии таких тестов писать тесты ещё и на построение запросов — неясно зачем.
P>>>Я ж вам говорил — некорректный запрос в тестах может выдавать корректный результат. И примеры привел.
P>·>Я примеров не видел. Я видел "объяснения".
P>Мы уже проходили — код всегда частный случай, на что у вас железный аргумент "у нас такой проблемы быть не может принципиально"
Код — это формальный язык. По нему сразу видно все ошибки. То что ты стесняешься написать формально — означает, что у тебя из аргументов только словоблудие, на ходу меняешь смысл терминов.
P>>>Валидность вообще всех запросов проверить не выйдет — та самая data complexity. Зато можно проверить известные проблемы для тех случаев, когда точная комбинация входа неизвестна.
P>·>Как? Ты это Проблему Останова решил тестами?
P>Не я, а вы. Это у вас комбинации покрываются repo+db тестами. А мне достаточно гарантировать наличие свойства запроса. см пример с LIMIT 10 выше. И это свойство сохранится на все времена, а потому проблема останова для меня здесь неактуальна.
Гарантировать наличие любого нетривиального свойства у кода (а запрос — это код) — алгоритмически неразрешимая задача (т. Райса), значит тесты тут никоим образом не помогут.
P>·>Ложная альтернатива. Ты "забыл" вариант: гонять через базу все возможные кейсы что есть в бд прода, или нам известно, что такие будут.
P>Скажите честно, сколько уникальных тестов у вас всего в проекте, всех уровней, видов, итд? И сколько у вас таблиц и связей в бд?
P>Моя оценка — уникальных тестов у вас самое большее 1000 помножить на число девелоперов. А тестов "комбинаций" из этого будет от силы 1%.
P>Итого — сколько тестов , таблиц, связей?р
Цифры я ниже привёл. Базы мелкие, да, ну может порядка сотни таблиц.
P>>>·>Я до сих пор не понимаю почему у тебя есть проблема с загрузкой всей бд в память, решается же элементарно.
P>>>Вы до сих пор не показали решения. Комбинация параметров вам неизвестна. Действуйте.
P>·>Только после вас.
P>Я уже привел кучу примеров. А вы всё никак.
Нигде не было неизвестных комбинаций параметров, не ври.
P>·>И что ты будешь ассертить в твоём тесте? sql.contains("LIMIT 1000")?
P>Зачем contains ? Проверяться будет весь паттерн запроса, а не его фрагмент.
Как именно?
P>>>Это именно ваш подход — записать три значения в бд и надеяться что этого хватит. А как протестировать "запрос не тащит откуда не надо" вы не показали.
P>·>Показал. Запрос должен из условных трёх записей выбирать только условно две.
P>Не работает. Фильтры могут тащить из херовой тучи таблиц, связей итд. Вам надо самое меньшее — заполнение всех возможных данных, таблиц, связей и тд. И так на каждый тест.
Работает. И не на каждый тест, а на прогон практически всех тестов.
P>У вас здесь сложность растет экспоненциально.
Не растёт.
P>>>Вы дурака валяете? deep.eq.pattern это тест для п2. Тесты для п1 — обычные интеграционные.
P>·>Я читаю что написано.
P>Ну сейчас то понятно, что интеграционные никто не отменял, или еще месяц-два будете это игнорировать?
Я задал вопрос. Ты его удалил не ответив.
P>·>Давай цифири приведу. В типичном проекте какие мне доводилось наблюдать таких юзкекйсов порядка 100k при более-менее хорошо организованном тестировании. Каждый интеграционный тест вида "...UI workflow с навигацией от логина..." это порядка нескольких секунд, даже без учёта разворачивания и подготовки инфры. Прикинь сколько будет занимать прогон всех таких тестов. В реальности интеграцией можно покрыть от силы 1% кейсов. Если это, конечно, не хоумпейдж.
P>100к юзкейсов протестировать сложно, а написать легко? Чтото тут не сходится.
Ты откуда нателепатировал "сложно/легко"? Я написал про скорость прогона тестов.
P> Вы вероятно юзкейсом называете просто разные варианты параметров для одного и того же вызова контроллера.
Юзкейс — это в первом приближении кусочек спеки из бизнес-требования, одна хотелка заказчика.
P>>>На каждую комбинацию накидать минимальную бд — уже мало реально.
P>·>Я тебе уже объяснял. Не надо накидывать бд на каждую комбинацию. Какие-то жалкие 30 (тридцать!) записей можно фильтровать миллиардом (230) уникальных способов, без учёта сортироваки.
P>Похоже, вы точно не понимаете data complexity.
P>Эти 30 комбинаций разложить по таблицам и колонкам и окажется в среднем около нуля на большинстве комбинаций фильров.
Почему так окажется? "все
возможные кейсы что есть в бд прода, или нам известно, что такие будут.", т.е. раскладываются различные с т.з. бизнеса сущности, а не просто "Account 1", "Account 2".
P>>>Т.е. каждая комбинация это тесты вида "тащим откуда надо" + тесты вида "не тащим откуда не надо" коих много больше.
P>·>Не так, а так: для комбинации X выбираем эти 7 записей из 30.
P>См выше — вы разложили 30 записей по таблицами и колонкам и в большинстве случаев у вас выходит 0 значений. А потому 7 из 30 это ни о чем.
P>Соответственно, пускаете фильтр на проде, и приложение вгружает базу целиком.
Бред.