Здравствуйте, ·, Вы писали:
Вспомнил ваше утверждение про покрытие интеграционными тестами. Смотрите, что вы пишете в очередной раз:
> В реальности интеграцией можно покрыть от силы 1% кейсов.
Помните? Вот здесь вы написали обоснование тем самым тестам на проде. Оставшиеся 99% ваши моки не заткнут, как бы вы не старались. Хоть обпишитесь. И даже если вы обмажетесь всеми возможными юнит-тестами, моками, какими угодно — покрытие интеграционными тестами в 1% говорит о том, что за продом нужно наблюдать более серьезными методами, нежели ваши health check.
Для этого подходят e2e тесты — один такой тест может затронуть чуть не половину всех юзкейсов в приложении.
Если же вы хотите заткнуть 99% непокрытых юзкейсов мониторингом на основе с healthcheck — чтото здесь не сходится.
P>>·>Действительно. Какой смысл искать верное решение задачи, если в предыдущем были ошибки. Отличная логика!
P>>Вы пока ошибок не показали. Основная ваша придирка в том, что структурная эквивалентность не нужна, хрупкая, итд — при этом альтернативы такому решению у вас нет.
·>Это и есть ошибка. Плюс показал потенциальные ошибки например с дефолтным значением vs null. Альтернативу тоже показал. Происто ты проигнорировал.
Вы показали теоретически возможные ошибки при построении запроса "а вдруг не учтем дефолтное значение". Ну так это и у вас будет — если чего то не учтете.
Ваша альтернатива не работает — упираемся в конское количество колонок, связей и разнообразия свойств внутри джсона — так вот всё хранится.
И ваш подход к тестированию фильтров не палит.
P>>А вот изменение имени пользователя спустя секунду после создания — очень даже адекватно.
·>Ты путаешься в показаниях. Ты сам-то адекватен? Откуда взялось "50мс"??! Ты тут сказал, что синхронное сохранение внезапно заменил на асинхронное и у тебя возникли проблемы с тем, что теперь другой метод можно позвать только через 5 минут.
Я такого не говорил — это вы начали фантазировать, что придется ждать 5 минут и никак иначе не выйдет. Обоснования у вас никакого нет.
P>>public ssl key — ничего военного. Пересоздавать этот кей спустя секунду после создания занятие абсолютно бессмысленное. А вас послушать, так окажется что любые данные ассоциированые с пользователем могут меняться сразу же, включая гуиды ссылок на любую глубину связности.
·>Я не знаю что это и какое это всё имеет отношение к обсуждаемому.
Я вам привел пример, что данные разделяются на те, что нужны сейчас, и те, что нужны потом, когда нибудь. Так не бывает, что всё всегда нужно сразу на любую глубину вложенности.
Если у вас хватает капасити обработать всё за один реквест — отлично. Самый простой вариант, без какого либо усложения архитектуры.
Как только вашего капасити перестает хватать — см требованиия, там написано, что из данных юзера нужно сразу, а что нет.
P>>Я вот почему то уверен, что несмотря на эти цитаты вы еще месяц или два будете мне доказывать, что я тестирую только юнит-тестами.
·>Ты пишешь бред. Я задаю вопрос, ты игнорируешь и снова повторяешь то же самое. Попробуем ещё раз:
·>Я читаю что написано. В цитате выше написано "тестируется" (само как-то?), потом стоит запятая и слово "далее" и про интеграционные тесты. Если эта твоя цитата не говорит что ты хочешь сказать, переформулируй, у меня очень плохо с телепатией.
Цитирую себя N+3й и N+4й разы — выделил
п1 — паттерн тестируется на бд, далее — интеграционными тестами
...
1. рабочий паттерн запроса — это проверяется сначала руками, а потом тестом против бд минимально заполненой под задачу
P>>Пример недостаточно информативный. А вот сам подход — проверять построение запроса — очень даже хороший.
·>Т.е. код не был даден. ЧТД. Куда отматывать-то?
Структурная эквивалентность запроса — все что надо, было показано. Вам десяток страниц кода билдера фильтров показать или что?
P>>Какого угодно. Если вам для запроса данных нужна цепочка джойнов или вложеный запрос — то это и есть паттерн.
·>Это ты цель со средством путаешь. Мне надо чтобы запрос выдавал результат который нужен по спеке. А что там — цепочка джойнов или чёрт лысый — абсолютно пофиг. Более того, если сегодня написали запрос с джойнами, а завтра, после разговора с dba его переписали на вложенный — то ни один тест упасть не должен.
Я ж вам сразу сказал — такой тест более хрупкий. Его нужно применять ради решения конкретных проблем, а не лепить вообще везде. Одна из проблема — те самые фильтры.
P>>А так же надо учесть вещи вида "не делает то чего делать не должен".
·>Мы говорим о тестах. Как тебе тесты помогут что-то гарантировать? Причём тут тесты??!
Тесты пишутся именно ради гарантий:
1 делает что надо
2 не делает того, чего не надо
P>>Все что передается в eq — паттерн для теста. А ' наш конкретный запрос' тут проверяем паттерн запроса к бд.
·>Здесь в коде это просто строка полного sql-запроса, которая сравнивается по equals. Я не понимаю почему ты это называешь паттерном, что в тут паттернится-то?
Паттерн — потому, что название даётся по назначению. Назначение этого подхода — проверять построеный запрос на соответствие паттерну.
Если у вас есть более эффективный вариант, например, json-like или AST на алгебраических типах данных, будет еще лучше
P>>Например, для эластика у вас будет обычный http запрос.
P>>Можно точно так же проверять запросы к ORM. Это решает проблемы с джигитам "я быстренько, там всё просто"
·>Ясно. Так я код с такими "паттернами" пишу как раз когда надо "я быстренько, там всё просто". В серьёзных ситуациях за такое надо бить по рукам.
Проблема с фильтрами вполне себе серьезная. А вы никак адекватного решения не предложите.
P>>Вы показали примитивные тесты вида "положили в таблицу, проверили, что нашли положенное". А как протестировать "не нашли неположенного" или "не начали вгружать вообще всё" — вы такого не показали.
·>Показал. Ещё раз разжую. Минимальный пример: Если мы в таблицу кладём "Vasya", то при поиске, например по шаблону по startsWith("Vas") — должны найти одну запись, а по startsWith("Vaz") — ноль. Второй тест как раз и ассертит, что твой этот фильтр не вгружает всё, а только то, что должно было заматчиться. Ещё раз. Одна запись в БД — это 21 вариантов результата, которые можно различить.
Очень смешно. Как ваш пример экстраполировать на полторы сотни свойств разного рода — колонки, свойства внутри джсон колонокк, таблиц которые могут джойнами подтягиваться?
Вы ранее говорили — 30 значений положить в бд. Это значит, что 120 свойств будут незаполнеными, и мы не узнаем или ваш запрос фильтрует, или же хавает пустые значения которые в проде окажутся непустыми.
P>>И то, и другое вашими примитивными тестами не решается.
·>Решается.
Нисколько. Если вы положили в таблицу Vasya, то к нему нужно подкинуть полторы сотни так или иначе связанных с ним свойств. Не 30, как вам кажется, а минимум 150. И желательно, что бы таких васей было больше одного.
Фильтр будет не startwith, а
1. конское количество условий — приоритеты, скобки
2. паттерны строк что само по себе хороший цирк
3. джойны в зависимости от условий итд
4. приседания с джсон разной структуры
5. группировки, агрегирование, итд
Например — найти всех вась которые между июнем и июлем делали повторные возвраты товаров из перечня которые были куплены между январем и мартом оформлены менеджерами которые были наняты не позже декабря прошлого года и получив % от сделок уволились с августа по сентябрь
Еще интереснее — найти все товары, которые двигались во всей этой кунсткамере.
P>>Интеграционные нужны для проверки, что репо умеет работать с бд, а вовсе не для проверок комбинаций. Для проверок комбинаций есть другие методы, гораздо более эффективные.
·>Что значит "умеет работать"?
Например, репозиторий Users метод create — параметры — данные юзера, возвращаемое значение — созданный юзер + ассоциированные данные. Нас интересует
1. разложит данные юзера в соответствии со схемой, подкинет гуид где надо
2. построит запрос один или несколько, сколько надо для той бд-сервиса-итд, что в конфигурации
3. отшлет вбд и вернет данные с запрошеными ассоциациями, иды, гуиды — будут соответсвовать схеме, входным данным итд
4. подклеит метадату
5. повторый запрос с тем же гуид должен зафейлиться с конкретной ошибкой
6. такой же запрос с другим гуид должен выполнится хорошо
7. корректно пробрасывать ошибки вида "дисконнект бд из за рестарта"
8. сумеет в опции — ничего не тащить из бд если был флаг write-only
Вот такие вещи показывают интеграцию. Это если вы сами пишете репозиторий, а не берете его готовым в ОРМ фремворке.
Тесты на фильтры здесь минимальные — есть, нету, т.к. нам надо что репозиторий их строит и отдаёт в бд.
А вот всё множество комбинаций в фильтрах нужно покрывать совсем другими тестами.
P>>Вы только что "показали" — для проверок комбинций использовать интеграционный тест репо+бд
·>Почему нет-то?
Потому, что
1 это медленно
2 вы подкидываете небольшое количество значений. Смотрите пример фильтра с васями, только не ваш, а мой
P>>Могу. Например, для тестов которые тянут больше одной строки могу просто затребовать `LIMIT 10`.
·>Как?
Вот так:
`конский запрос LIMIT 10`
И добавить подобное в тесты всех критических запросов.
Т.е. это просто пост условие, и давать будет ровно те же гарантии.
P>>Мы уже проходили — код всегда частный случай, на что у вас железный аргумент "у нас такой проблемы быть не может принципиально"
·>Код — это формальный язык. По нему сразу видно все ошибки. То что ты стесняешься написать формально — означает, что у тебя из аргументов только словоблудие, на ходу меняешь смысл терминов.
С этим есть сложность — ваш код с тестами фильров, те самые васи, говорит о том, что мы с вами совершенно иначе понимаем data complexity
P>>Не я, а вы. Это у вас комбинации покрываются repo+db тестами. А мне достаточно гарантировать наличие свойства запроса. см пример с LIMIT 10 выше. И это свойство сохранится на все времена, а потому проблема останова для меня здесь неактуальна.
·>Гарантировать наличие любого нетривиального свойства у кода (а запрос — это код) — алгоритмически неразрешимая задача (т. Райса), значит тесты тут никоим образом не помогут.
Теорема Райса про алгоритмы и свойства функций, а не про код.
Забавно, что вы только что сами себе рассказали, почему любые ваши тесты без толку. Только такого рода гарантий тестами вообще никто никогда не ставит.
P>>Я уже привел кучу примеров. А вы всё никак.
·>Нигде не было неизвестных комбинаций параметров, не ври.
Это очевидно — никто не даст вам списка "вот только с этими комбинациями не всё в порядке". Вы будете узнавать о той или иной комбинации после креша на проде.
Поэтому вполне логично добавить пост-условие.
P>>Зачем contains ? Проверяться будет весь паттерн запроса, а не его фрагмент.
·>Как именно?
Вы то помните, то не помните. В данной задаче — просто сравнением sql. Назначение теста — зафиксировать паттерн.
P>>Не работает. Фильтры могут тащить из херовой тучи таблиц, связей итд. Вам надо самое меньшее — заполнение всех возможных данных, таблиц, связей и тд. И так на каждый тест.
·>Работает. И не на каждый тест, а на прогон практически всех тестов.
Т.е. вы уже меняете подход к тестам — изначально у вас было "записать три значения в бд и проверить, что они находятся фильтром"
P>>У вас здесь сложность растет экспоненциально.
·>Не растёт.
Растет. Докинули поле — нужно докинуть данных на все случаи, где это будет играть, включая паттерны строк, джойны, итд итд.
P>>Ну сейчас то понятно, что интеграционные никто не отменял, или еще месяц-два будете это игнорировать?
·>Я задал вопрос. Ты его удалил не ответив.
Цитирую себя N+5й и N+6й разы — выделил
п1 — паттерн тестируется на бд, далее — интеграционными тестами
...
1. рабочий паттерн запроса — это проверяется сначала руками, а потом тестом против бд минимально заполненой под задачу
P>>100к юзкейсов протестировать сложно, а написать легко? Чтото тут не сходится.
·>Ты откуда нателепатировал "сложно/легко"? Я написал про скорость прогона тестов.
Вот видите — это у вас времени на тесты не хватает, т.к. логику да комбинации вы чекаете на реальной бд
P>> Вы вероятно юзкейсом называете просто разные варианты параметров для одного и того же вызова контроллера.
·>Юзкейс — это в первом приближении кусочек спеки из бизнес-требования, одна хотелка заказчика.
Вам надо определиться — не то есть тесты, не то нету.Код написан — должны быть тесты. А на комбинации времени не хватает, т.к. через бд гоняете.
P>>Эти 30 комбинаций разложить по таблицам и колонкам и окажется в среднем около нуля на большинстве комбинаций фильров.
·>Почему так окажется? "все возможные кейсы что есть в бд прода, или нам известно, что такие будут.", т.е. раскладываются различные с т.з. бизнеса сущности, а не просто "Account 1", "Account 2".
У вас комбинаций меньше чем условий в фильтре.