Сообщение Re[89]: Что такое Dependency Rejection от 07.03.2024 10:53
Изменено 08.03.2024 8:33 Pauel
Re[89]: Что такое Dependency Rejection
Здравствуйте, ·, Вы писали:
P>>моки и конформационные тесты это не решение, а компенсация.
·>Способ экономии ресурсов.
Имено — за счет покрытия.
P>>Вы отказываетесь идти дальше, и делать внятное покрытие e2e, и посмеиваетесь с тех, кто всё таки покрывает эти 99% как следует.
·>Скорее завидую простоте системы, что её реально покрыть e2e на 99%.
Вы сами себя ограбили когда строили вашу пирамиду тестов в виде трапеции — полуинтеграционные на моках + конформанс, которые к вашей системе имеют слабое отношение.
P>>Пример у вас есть внятный? Мне непонятно, каким чудом моки репозитория помогут понять, что же с интеграцией не так.
·>Они не для этого.
В том то и дело — вы оставили себе только полуинтеграционные тесты на моках.
Юнит-тесты вы не пишете, т.к. "это детали реализации, их не надо писать"
e2e "слишком долго"
P>>Какой компоент системы вы собираетесь конф тестами покрывать?
·>Конф-тесты тестируют чужое api. Система (по крайней мере её прод-часть) не принимает участие в конф-тестах.
Про то и речь — про интеграцию ваших компонентов с другими вашими же компонентами они ничего не говорят.
P>>Расскажите внятно, как мок репозитория поможет вам с интеграцией уровня приложения?
·>Никак. Мок поможет тестировать часть приложения с меньшим количеством ресурсов, следовательно позволит иметь больше покрытых сценариев.
В сценариях нас интересует интеграция прежде всего.
Например — юзер регистрируется, уточняет сведения, подтверждает регистрацию, делает N действий, смотрит в аудит, все ли хорошо, и делает логаут.
Итого:
Данные от входного запроса POST /users будут передаваться как положено во все части системы, и обратно, и это будет отражено везде — в профайле юзера, во всех частях админке
А далее, апдейт того же юзера снова даст ожидаемый результат и в профайле, и во всех частях админки
И так со всеми действиями согласно сценарию до самого последнего.
Если вы моками нарезали весь этот путь на части, вы знаете, что внутри каждой из частей всё хорошо
А вот склейку всех частей тестируют тесты системного уровня, например, те самые e2e
P>>Наоборот, e2e показывает те ошибки, которые проходят мимо ваших моков.
·>Если оно это показывает случайно, через несколько часов — то это называется хрень, а не показания.
Это намного лучше, чем их отсутствие.
P>> Они показывают, что приложение склеено как положено.
·>Это и проблема твоего подхода — у тебя в приложении на строчку кода ведро клея, который никак и не тестируется, кроме как тонной e2e.
Обратите внимание — сколько бы я вам ни говорил про юнит-тесты и интеграционные, вы всё равно видите своё.
Я даже цифры привел
Еще раз
e2e — меньше всего, десятки
интеграционные, функциональные — x10..x100 раз больше чем e2e
юнит-тесты, компонентные — x10..x100 раз больше, чем интеграционных
Вы выбросили:
верхний уровень — долго,
нижний — это "детали реализации"
Сверх этого кастрировали средний уровень и получили полуинтеграционные на моках
Итого — от вашей пирамиды остался поясок стыдливости
P>>Ну да — вы забили на интеграционные тесты.
·>Ну так в моём подходе этой интеграции кот наплакал, поэтому "приложение не упало при старте" уже практически означает, что 100% тех ошибок, "которые проходят мимо ваших моков" показано.
Это иллюзия. В сложном приложении интеграция не может быть простой, по определению.
Если у вас есть несколько источников данных для времени, то нужно гарантировать, что все они прописаны корректно для соответствующих юз кейсов
Как это проверяется стартом приложения — не ясно.
P>>·>Не годится. Мы не можем релизиться только с тремя десятками сценариев. Надо проверять 100%.
P>>Я ж вам не предлагаю выбросить — я вам предлагаю добавить, и показываю, как именно.
·>Добавлять тест, который запускается рандомно через раз — это какое-то извращение. Если некий тест запускать не обязательно для релиза, клиенты переживут и так — накой его вообще запускать?
Вы и запускаете его для релиза — только результаты собираете не разово, а в течение первых часов после деплоя.
Здесь важно обнаружить проблемы раньше юзеров на проде.
Очевидно, что если собирать сведения не раз. а несколько часов, то сведений будет больше, и диагностика будет точнее
P>>Вы уже релизитесь без 99%. Если к вашим тестами добавите e2e, то покрытие станет плотнее.
·>Не станет.
e2e регулярно находят проблемы которые другими тестам даже обнаружить сложно.
P>>Если не хватает времени — e2e можно гонять и после деплоймента, хоть круглые сутки, они хлеба не просят.
·>Зачем? Если они что-то обнаружат, это значит что у клиентов проблемы прямо сейчас, prod incident. Поздно борожоми пить.
Затем, что бы
1 обнаружить на самых ранних этапах
2 сразу собрать максимальное количество сведений. По этим тестам у вас больше всего сведений, как и что воспроизвестир
Юзеры
1 репортают проблемы не сразу, а с большой задержкой
2 репортают не все сведения, а часто еще и лишних подкидывают
P>>Вы уже это делаете. e2e всего то сделают видимыми проблемы в тех 99% которые ходили мимо ваших моков.
·>Ещё раз. Если ты догадался нечто описать в виде теста, пусть e2e — это значит какой-то вполне определённый известный сценарий. Всегда есть возможность покрыть этот сценарий покрыть более дешёвыми тестами и выполнять до релиза, всегда, а не по броску монеты.
Сценарии и так покрыты дешовыми тестами. Эти дешовые тесты, особенно на моках, не покрывают всю интеграцию, что очевидно.
См пример сценария выше.
P>>Это способ выполнять те тесты, которые у вас вообще отсутствуют.
·>Потому что нахрен не нужны.
Вот это ваш самый частый аргумент вместе с "словоблудие" итд
P>>Вы тестируете минимально, репозиторий + бд. Эта часть есть и у меня.
·>Где конкретно эта часть есть у тебя? Ты заявлял, что в твоих pattern-тестах ты репозиторий + бд не тестируешь; а в e2e ты каждую переменную на null тестирвать не будешь, да и не сможешь.
Там же где и у вас — это часть интеграционных тестов.
P>>Комбинации различных условий в фильтре, что дает нам ту самую data complexity, и проблемные комбинации вы будете узнавать только на проде, одну за другой
·>Ты тоже.
Именно. И я этим знанием пользуюсь, а вы — нет. например, я точно знаю, как выглядит проблема с фильтрами — вгружается вообще всё. Соответсвенно вариантов решения у меня несколько
Даже если я не знаю комбинации, то могу подстараховаться пост-условием
А что бы пост-условие не потерялось, подкидываю тест
·>Причём тут текущее время? Проблема как раз была в том, что ты называешь "нефункциональные требования": "ну юзер же создался, а что ещё не совсем до конца создался, ничего страшного..".
Именно это нефункциональные требования и описывают — когда именно произойдет событие "юзер создался до конца". Вот здесь как правило запас по времени существенный.
Чем вы и пользуетесь для изменения дизайна
P>>Вот-вот. И если BA даёт добро — всё хорошо.
·>Ну вот это "добро" тебе и надо будет выразить в тестах.
Разумеется.
P>>Уже в который раз уточняю, но вы всё равно видите чтото свое
·>В прыжке переобуваешься. Это совершенно не то, что ты изначально утверждал "БЛ начала вызываться через очередь, с задержкой от часов до дней". Написал "БЛ", а на самом деле телепатировал, есть части логики нужные сейчас, а есть части не сейчас. Если ты не понимаешь как это выражается с моками, задавай вопросы, а не фантазируй проблемы.
Что вас смущает? БЛ вызывается из разных мест приложения. Ключевое — консистентность тех или иных сведений.
P>>·>Из слов "паттерн тестируется" неясно кем.
P>>Если руками, что следует из выделеного, то какие варианты?
·>Мде, отстой.
Расскажите, как лучше. Желательно на тех самых фильтрах — откуда возьмете первый вариант запроса к бд, орм, нужное-вписать, и как будете его тестировать
P>>Я вам выделил, что бы виднее было.
·>Что за тест "против бд минимально заполненой под задачу"? Какие части системы он тестирует? e2e? или связка репо+бд? Или ещё что?
В зависимости от конкретного дизайна:
репозиторий + бд — если все запросы генерируются самим репозиторием
юз-кейс + репозиторий + бд — если у нас генерация выражений находится вне репозитория
P>>Не работает — вы не знаете проблемной комбинации для фильтров. Знаете только что они есть и их хрензнаетсколькилион
·>Комбинация ровно та же — что и в твоём тесте. Тест почти такой же — только вместо деталей реализации ассертится поведение.
Что вы будете ассертить в поведении?
P>>Что бы исключить ту самую проблему в явном виде — потенциальная загрузка всего содержимого таблицы.
·>Эта проблема не исключается тестом, как бы тебе это ни хотелось.
И давно у вас пост-условие стало тестом ?
P>>Покрывается. Я ж вам показал. Только решение и покрытие это разные вещи. В данном случае решение — постусловие. А тестами фиксируем, что бы не убежало
·>Что значит "не убежало"?
Пришел некто резкий и дерзкий и фиксанул "тут всё просто, я быстро". На его тестовой бд записей 60 штук, мелочовочка. А на проде это десятки миллионов.
P>>Покажите пример регрессии, которая не будет обнаружена этим тестом.
·>Ну загрузится пол таблицы.
Полтаблицы это 20 записей? Не понял, что за кейс такой.
> Или банально твой .top(10) не появится для какой-то конкретной комбинации фильтров, т.к. для этой комбинации решили немного переписать кусочек кода и забыли засунуть .top(10).
Что значит не появится? Если это пост-условие,оно будет применено для всего выхлопа, а не для разных подветок в вычислениях.
P>>Необязательно. Если я руками пишу весь запрос — то будет в коде явно. но запрос может и билдер создать.
·>Магически что-ли? Билдер рандомно top(10) не вставит, будет некий кусок кода который его ставит.
Поскольку билдер сложный, то можно сказать, что да, магически — прямой связи входа и выхода вы на глазок не обнаружите. Потому и надо подстраховываться в тестах.
P>>Некоторые детали нужно фиксировать в тестах, что бы случайно залетевший дятел не разрушил цивилизацию.
·>Дятлы тесты тоже умеют редактировать.
Умеют — здесь только код-ревью может помочь. О чем я вам и говорю в который раз.
> А с учётом того, что у тебя в тестах полный текст sql — то это будет простой copy-paste и вечнозелёный тест. А на ревью определить корректность sql на вид могут не только лишь все.
В данном случае и не нужно, что бы все могли определять корректность — код заведомо нетривиальный.
P>>Решение — пост-условие. А вот тест который я показал, он всего то гарантирует сохранность этого пост-условия.
·>Не гарантирует.
Видите — снова без аргументов, голословно
P>>Если вы не можете сделать этого руками, то ваши попытки выразить это в коде и генерации данных будут иметь ту же особенность.
·>Ты не понял. Я могу сделать это не руками, а кодом.
Для простых фильров это работает. Для сложных — проще найти решение напрямую, в бд, что бы представлять, куда всё двигать
P>>Есть и такие — их проще писать сразу, проще отдладить по горячим следам.
P>>Но с ростом сложности приходится вводить дополнительные инструменты.
·>Это где ты говорил такое месяц назад? Цитату.
Вам не только я, но и Синклер это же сказал.
P>>Пост-условия похоже для вас пустой звук, вам это всё равно кажется тестом. Тест всего лишь гарантирует сохранность пост-условия
·>Не гарантирует.
У вас похоже тесты вообще ничего не гарантируют. Зачем же вы их пишете?
P>>И решения и у меня, и у вас, для подобных кейсов будут одни и те же.
·>Ну может быть колонок id несколько разных и иногда они совпадают... но не всегда.
каким образом в одной таблице users может быть несколько колонок id ? byId — это запрос к праймари кей. Ломается только если схема поломана.
P>>Вы снова чего то фантазируете.
·>Что фантазирую? Это вроде ты предлагаешь в код вставлять top(10) и тестом "фиксировать".
Это же пост-условие.
P>>Нет, не могут. Так, как это утверждает т. Райса — вы true от false отличить не сможете. Можете потренироваться — тестами обнаружить функцию, которая всегда возвращает true. Валяйте.
·>"всегда" — это уже нетривиальное свойство. Проверка тривиального свойства это по сути "выполнить код и поглядеть на результат", т.е. тест практически.
Ловко вы опровергли теорему Райса!
В т.Райса нетривиальное свойство означает, что есть функции, которые им обладают, а есть те, которые не обладают.
P>>Как наиграетесь, приходите
·>Не понял. Да, эта функция возвращает true. Тестом будет "f=() -> true; assertTrue(f())".
Вот-вот. Опровержение теоремы Райса!
P>>Смотрите выше, текст выделен H1, как раз эту вашу способность и "демонстрирует"
·>Так ещё до того как ты это написал уже говорил, что _необходимость_ ручного тестирования — проблема. Не надо так делать и рассказал как избежать эту необходимость.
Ручное тестирование плохо не само по себе, а когда оно увеличивает время разработки
А когда сокращает — очень даже хорошо
В данном случае подобрать тот самый нетривиальный запрос к бд — вашими косвенными методами вы можете уйти куда угодно и оставить сколько угодно дыр
P>>Хрупкий — это я вам сразу сказал.
Я снова выделил, что бы вам виднее было. Посимвольно это потому, что у меня в конкретном случае нет ни json, ни orm, ни еще какого ast.
deep.eq дает нам вполне годную структурную эквивалентность.
Если вы ей не умеете пользоваться — значит это не ваш вариант
P>>Да то, что искать тестами проблемные комбинации вы вспотеете. Нужно искать решение вне тестов.
·>Ясен пень, тестами комбинации не ищутся, а тестируются. Анализируешь код, coverage report, логи, спеки и т.п., потом пишешь тест подозрительной комбинации и смотришь как себя система ведёт.
И так будете для каждой комбинации, да? Дадите шанс юзеру убиться об ваш билдер фильтров?
P>>Ну можете не руками, а попросить того, кто знает схему бд и язык запросов к ней.
·>А этот кто-то как будет, ногами что-ли?
·>Ок, допустим ногами. А какие в базе будут данные на которой этот чаи-гпт будет проверять свои запросы вножную? За 2025 год, правильно?
Жалко, что нет шрифта больше чем h1
сначала руками, а потом тестом против бд минимально заполненой под задачу
P>>Почему первые запуски — потому, что после них как раз будет известен паттерн, по которому нужно будет строить запросы. дальше в ручных проверках смысла не много.
·>Потом система меняется и паттерн перестаёт функционировать проверенным вручную способом, а тестам — пофиг, они вечнозелёные.
А интеграционные тесты вы забыли, да?
Мне что, каждую строчку теперь H1 выделять, что бы вам виднее было?
P>>С фильтрами комбинаций столько, что солнце погаснет раньше ваших тестов.
·>Даже если и так, то до e2e-комбинаций и жизни Вселенной не хватит уж точно.
В том то и дело — количество e2e никак не зависит от количества комбинаций в фильтрах.
P>>Проблема в том, что бы генерить данные, нужно знать комбинации которые будут проблемными.
·>Это же требуется и для того чтобы чтобы руками проверять запросы.
Похоже, пост-условия для вас пустой звук. Для моего варианта нужно проверить,
1 работает ли пост-условие
2 находится ли оно на своем месте
3 все ли ветки ифов получат его
Вот это — решение. А тестами фиксируем сохранность этого условия. Т.е. тесты это второстепенная роль в данном случае.
P>>моки и конформационные тесты это не решение, а компенсация.
·>Способ экономии ресурсов.
Имено — за счет покрытия.
P>>Вы отказываетесь идти дальше, и делать внятное покрытие e2e, и посмеиваетесь с тех, кто всё таки покрывает эти 99% как следует.
·>Скорее завидую простоте системы, что её реально покрыть e2e на 99%.
Вы сами себя ограбили когда строили вашу пирамиду тестов в виде трапеции — полуинтеграционные на моках + конформанс, которые к вашей системе имеют слабое отношение.
P>>Пример у вас есть внятный? Мне непонятно, каким чудом моки репозитория помогут понять, что же с интеграцией не так.
·>Они не для этого.
В том то и дело — вы оставили себе только полуинтеграционные тесты на моках.
Юнит-тесты вы не пишете, т.к. "это детали реализации, их не надо писать"
e2e "слишком долго"
P>>Какой компоент системы вы собираетесь конф тестами покрывать?
·>Конф-тесты тестируют чужое api. Система (по крайней мере её прод-часть) не принимает участие в конф-тестах.
Про то и речь — про интеграцию ваших компонентов с другими вашими же компонентами они ничего не говорят.
P>>Расскажите внятно, как мок репозитория поможет вам с интеграцией уровня приложения?
·>Никак. Мок поможет тестировать часть приложения с меньшим количеством ресурсов, следовательно позволит иметь больше покрытых сценариев.
В сценариях нас интересует интеграция прежде всего.
Например — юзер регистрируется, уточняет сведения, подтверждает регистрацию, делает N действий, смотрит в аудит, все ли хорошо, и делает логаут.
Итого:
Данные от входного запроса POST /users будут передаваться как положено во все части системы, и обратно, и это будет отражено везде — в профайле юзера, во всех частях админке
А далее, апдейт того же юзера снова даст ожидаемый результат и в профайле, и во всех частях админки
И так со всеми действиями согласно сценарию до самого последнего.
Если вы моками нарезали весь этот путь на части, вы знаете, что внутри каждой из частей всё хорошо
А вот склейку всех частей тестируют тесты системного уровня, например, те самые e2e
P>>Наоборот, e2e показывает те ошибки, которые проходят мимо ваших моков.
·>Если оно это показывает случайно, через несколько часов — то это называется хрень, а не показания.
Это намного лучше, чем их отсутствие.
P>> Они показывают, что приложение склеено как положено.
·>Это и проблема твоего подхода — у тебя в приложении на строчку кода ведро клея, который никак и не тестируется, кроме как тонной e2e.
Обратите внимание — сколько бы я вам ни говорил про юнит-тесты и интеграционные, вы всё равно видите своё.
Я даже цифры привел
Еще раз
e2e — меньше всего, десятки
интеграционные, функциональные — x10..x100 раз больше чем e2e
юнит-тесты, компонентные — x10..x100 раз больше, чем интеграционных
Вы выбросили:
верхний уровень — долго,
нижний — это "детали реализации"
Сверх этого кастрировали средний уровень и получили полуинтеграционные на моках
Итого — от вашей пирамиды остался поясок стыдливости
P>>Ну да — вы забили на интеграционные тесты.
·>Ну так в моём подходе этой интеграции кот наплакал, поэтому "приложение не упало при старте" уже практически означает, что 100% тех ошибок, "которые проходят мимо ваших моков" показано.
Это иллюзия. В сложном приложении интеграция не может быть простой, по определению.
Если у вас есть несколько источников данных для времени, то нужно гарантировать, что все они прописаны корректно для соответствующих юз кейсов
Как это проверяется стартом приложения — не ясно.
P>>·>Не годится. Мы не можем релизиться только с тремя десятками сценариев. Надо проверять 100%.
P>>Я ж вам не предлагаю выбросить — я вам предлагаю добавить, и показываю, как именно.
·>Добавлять тест, который запускается рандомно через раз — это какое-то извращение. Если некий тест запускать не обязательно для релиза, клиенты переживут и так — накой его вообще запускать?
Вы и запускаете его для релиза — только результаты собираете не разово, а в течение первых часов после деплоя.
Здесь важно обнаружить проблемы раньше юзеров на проде.
Очевидно, что если собирать сведения не раз. а несколько часов, то сведений будет больше, и диагностика будет точнее
P>>Вы уже релизитесь без 99%. Если к вашим тестами добавите e2e, то покрытие станет плотнее.
·>Не станет.
e2e регулярно находят проблемы которые другими тестам даже обнаружить сложно.
P>>Если не хватает времени — e2e можно гонять и после деплоймента, хоть круглые сутки, они хлеба не просят.
·>Зачем? Если они что-то обнаружат, это значит что у клиентов проблемы прямо сейчас, prod incident. Поздно борожоми пить.
Затем, что бы
1 обнаружить на самых ранних этапах
2 сразу собрать максимальное количество сведений. По этим тестам у вас больше всего сведений, как и что воспроизвестир
Юзеры
1 репортают проблемы не сразу, а с большой задержкой
2 репортают не все сведения, а часто еще и лишних подкидывают
P>>Вы уже это делаете. e2e всего то сделают видимыми проблемы в тех 99% которые ходили мимо ваших моков.
·>Ещё раз. Если ты догадался нечто описать в виде теста, пусть e2e — это значит какой-то вполне определённый известный сценарий. Всегда есть возможность покрыть этот сценарий покрыть более дешёвыми тестами и выполнять до релиза, всегда, а не по броску монеты.
Сценарии и так покрыты дешовыми тестами. Эти дешовые тесты, особенно на моках, не покрывают всю интеграцию, что очевидно.
См пример сценария выше.
P>>Это способ выполнять те тесты, которые у вас вообще отсутствуют.
·>Потому что нахрен не нужны.
Вот это ваш самый частый аргумент вместе с "словоблудие" итд
P>>Вы тестируете минимально, репозиторий + бд. Эта часть есть и у меня.
·>Где конкретно эта часть есть у тебя? Ты заявлял, что в твоих pattern-тестах ты репозиторий + бд не тестируешь; а в e2e ты каждую переменную на null тестирвать не будешь, да и не сможешь.
Там же где и у вас — это часть интеграционных тестов.
P>>Комбинации различных условий в фильтре, что дает нам ту самую data complexity, и проблемные комбинации вы будете узнавать только на проде, одну за другой
·>Ты тоже.
Именно. И я этим знанием пользуюсь, а вы — нет. например, я точно знаю, как выглядит проблема с фильтрами — вгружается вообще всё. Соответсвенно вариантов решения у меня несколько
Даже если я не знаю комбинации, то могу подстараховаться пост-условием
А что бы пост-условие не потерялось, подкидываю тест
·>Причём тут текущее время? Проблема как раз была в том, что ты называешь "нефункциональные требования": "ну юзер же создался, а что ещё не совсем до конца создался, ничего страшного..".
Именно это нефункциональные требования и описывают — когда именно произойдет событие "юзер создался до конца". Вот здесь как правило запас по времени существенный.
Чем вы и пользуетесь для изменения дизайна
P>>Вот-вот. И если BA даёт добро — всё хорошо.
·>Ну вот это "добро" тебе и надо будет выразить в тестах.
Разумеется.
P>>Уже в который раз уточняю, но вы всё равно видите чтото свое
·>В прыжке переобуваешься. Это совершенно не то, что ты изначально утверждал "БЛ начала вызываться через очередь, с задержкой от часов до дней". Написал "БЛ", а на самом деле телепатировал, есть части логики нужные сейчас, а есть части не сейчас. Если ты не понимаешь как это выражается с моками, задавай вопросы, а не фантазируй проблемы.
Что вас смущает? БЛ вызывается из разных мест приложения. Ключевое — консистентность тех или иных сведений.
P>>·>Из слов "паттерн тестируется" неясно кем.
P>>Если руками, что следует из выделеного, то какие варианты?
·>Мде, отстой.
Расскажите, как лучше. Желательно на тех самых фильтрах — откуда возьмете первый вариант запроса к бд, орм, нужное-вписать, и как будете его тестировать
P>>Я вам выделил, что бы виднее было.
·>Что за тест "против бд минимально заполненой под задачу"? Какие части системы он тестирует? e2e? или связка репо+бд? Или ещё что?
В зависимости от конкретного дизайна:
репозиторий + бд — если все запросы генерируются самим репозиторием
юз-кейс + репозиторий + бд — если у нас генерация выражений находится вне репозитория
P>>Не работает — вы не знаете проблемной комбинации для фильтров. Знаете только что они есть и их хрензнаетсколькилион
·>Комбинация ровно та же — что и в твоём тесте. Тест почти такой же — только вместо деталей реализации ассертится поведение.
Что вы будете ассертить в поведении?
P>>Что бы исключить ту самую проблему в явном виде — потенциальная загрузка всего содержимого таблицы.
·>Эта проблема не исключается тестом, как бы тебе это ни хотелось.
И давно у вас пост-условие стало тестом ?
P>>Покрывается. Я ж вам показал. Только решение и покрытие это разные вещи. В данном случае решение — постусловие. А тестами фиксируем, что бы не убежало
·>Что значит "не убежало"?
Пришел некто резкий и дерзкий и фиксанул "тут всё просто, я быстро". На его тестовой бд записей 60 штук, мелочовочка. А на проде это десятки миллионов.
P>>Покажите пример регрессии, которая не будет обнаружена этим тестом.
·>Ну загрузится пол таблицы.
Полтаблицы это 20 записей? Не понял, что за кейс такой.
> Или банально твой .top(10) не появится для какой-то конкретной комбинации фильтров, т.к. для этой комбинации решили немного переписать кусочек кода и забыли засунуть .top(10).
Что значит не появится? Если это пост-условие,оно будет применено для всего выхлопа, а не для разных подветок в вычислениях.
P>>Необязательно. Если я руками пишу весь запрос — то будет в коде явно. но запрос может и билдер создать.
·>Магически что-ли? Билдер рандомно top(10) не вставит, будет некий кусок кода который его ставит.
Поскольку билдер сложный, то можно сказать, что да, магически — прямой связи входа и выхода вы на глазок не обнаружите. Потому и надо подстраховываться в тестах.
P>>Некоторые детали нужно фиксировать в тестах, что бы случайно залетевший дятел не разрушил цивилизацию.
·>Дятлы тесты тоже умеют редактировать.
Умеют — здесь только код-ревью может помочь. О чем я вам и говорю в который раз.
> А с учётом того, что у тебя в тестах полный текст sql — то это будет простой copy-paste и вечнозелёный тест. А на ревью определить корректность sql на вид могут не только лишь все.
В данном случае и не нужно, что бы все могли определять корректность — код заведомо нетривиальный.
P>>Решение — пост-условие. А вот тест который я показал, он всего то гарантирует сохранность этого пост-условия.
·>Не гарантирует.
Видите — снова без аргументов, голословно
P>>Если вы не можете сделать этого руками, то ваши попытки выразить это в коде и генерации данных будут иметь ту же особенность.
·>Ты не понял. Я могу сделать это не руками, а кодом.
Для простых фильров это работает. Для сложных — проще найти решение напрямую, в бд, что бы представлять, куда всё двигать
P>>Есть и такие — их проще писать сразу, проще отдладить по горячим следам.
P>>Но с ростом сложности приходится вводить дополнительные инструменты.
·>Это где ты говорил такое месяц назад? Цитату.
Вам не только я, но и Синклер это же сказал.
P>>Пост-условия похоже для вас пустой звук, вам это всё равно кажется тестом. Тест всего лишь гарантирует сохранность пост-условия
·>Не гарантирует.
У вас похоже тесты вообще ничего не гарантируют. Зачем же вы их пишете?
P>>И решения и у меня, и у вас, для подобных кейсов будут одни и те же.
·>Ну может быть колонок id несколько разных и иногда они совпадают... но не всегда.
каким образом в одной таблице users может быть несколько колонок id ? byId — это запрос к праймари кей. Ломается только если схема поломана.
P>>Вы снова чего то фантазируете.
·>Что фантазирую? Это вроде ты предлагаешь в код вставлять top(10) и тестом "фиксировать".
Это же пост-условие.
P>>Нет, не могут. Так, как это утверждает т. Райса — вы true от false отличить не сможете. Можете потренироваться — тестами обнаружить функцию, которая всегда возвращает true. Валяйте.
·>"всегда" — это уже нетривиальное свойство. Проверка тривиального свойства это по сути "выполнить код и поглядеть на результат", т.е. тест практически.
Ловко вы опровергли теорему Райса!
В т.Райса нетривиальное свойство означает, что есть функции, которые им обладают, а есть те, которые не обладают.
P>>Как наиграетесь, приходите
·>Не понял. Да, эта функция возвращает true. Тестом будет "f=() -> true; assertTrue(f())".
Вот-вот. Опровержение теоремы Райса!
P>>Смотрите выше, текст выделен H1, как раз эту вашу способность и "демонстрирует"
·>Так ещё до того как ты это написал уже говорил, что _необходимость_ ручного тестирования — проблема. Не надо так делать и рассказал как избежать эту необходимость.
Ручное тестирование плохо не само по себе, а когда оно увеличивает время разработки
А когда сокращает — очень даже хорошо
В данном случае подобрать тот самый нетривиальный запрос к бд — вашими косвенными методами вы можете уйти куда угодно и оставить сколько угодно дыр
P>>Хрупкий — это я вам сразу сказал.
Так я ж и не предлагаю посимвольное сравнение на все случаи жизни.
·>deep.eq по-другому тупо не умеет.Я снова выделил, что бы вам виднее было. Посимвольно это потому, что у меня в конкретном случае нет ни json, ни orm, ни еще какого ast.
deep.eq дает нам вполне годную структурную эквивалентность.
Если вы ей не умеете пользоваться — значит это не ваш вариант
P>>Да то, что искать тестами проблемные комбинации вы вспотеете. Нужно искать решение вне тестов.
·>Ясен пень, тестами комбинации не ищутся, а тестируются. Анализируешь код, coverage report, логи, спеки и т.п., потом пишешь тест подозрительной комбинации и смотришь как себя система ведёт.
И так будете для каждой комбинации, да? Дадите шанс юзеру убиться об ваш билдер фильтров?
P>>Ну можете не руками, а попросить того, кто знает схему бд и язык запросов к ней.
·>А этот кто-то как будет, ногами что-ли?
·>Ок, допустим ногами. А какие в базе будут данные на которой этот чаи-гпт будет проверять свои запросы вножную? За 2025 год, правильно?
Жалко, что нет шрифта больше чем h1
сначала руками, а потом тестом против бд минимально заполненой под задачу
P>>Почему первые запуски — потому, что после них как раз будет известен паттерн, по которому нужно будет строить запросы. дальше в ручных проверках смысла не много.
·>Потом система меняется и паттерн перестаёт функционировать проверенным вручную способом, а тестам — пофиг, они вечнозелёные.
А интеграционные тесты вы забыли, да?
Мне что, каждую строчку теперь H1 выделять, что бы вам виднее было?
P>>С фильтрами комбинаций столько, что солнце погаснет раньше ваших тестов.
·>Даже если и так, то до e2e-комбинаций и жизни Вселенной не хватит уж точно.
В том то и дело — количество e2e никак не зависит от количества комбинаций в фильтрах.
P>>Проблема в том, что бы генерить данные, нужно знать комбинации которые будут проблемными.
·>Это же требуется и для того чтобы чтобы руками проверять запросы.
Похоже, пост-условия для вас пустой звук. Для моего варианта нужно проверить,
1 работает ли пост-условие
2 находится ли оно на своем месте
3 все ли ветки ифов получат его
Вот это — решение. А тестами фиксируем сохранность этого условия. Т.е. тесты это второстепенная роль в данном случае.
Re[89]: Что такое Dependency Rejection
Здравствуйте, ·, Вы писали:
P>>моки и конформационные тесты это не решение, а компенсация.
·>Способ экономии ресурсов.
Имено — за счет покрытия.
P>>Вы отказываетесь идти дальше, и делать внятное покрытие e2e, и посмеиваетесь с тех, кто всё таки покрывает эти 99% как следует.
·>Скорее завидую простоте системы, что её реально покрыть e2e на 99%.
Вы сами себя ограбили когда строили вашу пирамиду тестов в виде трапеции — полуинтеграционные на моках + конформанс, которые к вашей системе имеют слабое отношение.
P>>Пример у вас есть внятный? Мне непонятно, каким чудом моки репозитория помогут понять, что же с интеграцией не так.
·>Они не для этого.
В том то и дело — вы оставили себе только полуинтеграционные тесты на моках.
Юнит-тесты вы не пишете, т.к. "это детали реализации, их не надо писать"
e2e "слишком долго"
P>>Какой компоент системы вы собираетесь конф тестами покрывать?
·>Конф-тесты тестируют чужое api. Система (по крайней мере её прод-часть) не принимает участие в конф-тестах.
Про то и речь — про интеграцию ваших компонентов с другими вашими же компонентами они ничего не говорят.
P>>Расскажите внятно, как мок репозитория поможет вам с интеграцией уровня приложения?
·>Никак. Мок поможет тестировать часть приложения с меньшим количеством ресурсов, следовательно позволит иметь больше покрытых сценариев.
В сценариях нас интересует интеграция прежде всего.
Например — юзер регистрируется, уточняет сведения, подтверждает регистрацию, делает N действий, смотрит в аудит, все ли хорошо, и делает логаут.
Итого:
Данные от входного запроса POST /users будут передаваться как положено во все части системы, и обратно, и это будет отражено везде — в профайле юзера, во всех частях админке
А далее, апдейт того же юзера снова даст ожидаемый результат и в профайле, и во всех частях админки
И так со всеми действиями согласно сценарию до самого последнего.
Если вы моками нарезали весь этот путь на части, вы знаете, что внутри каждой из частей всё хорошо
А вот склейку всех частей тестируют тесты системного уровня, например, те самые e2e
P>>Наоборот, e2e показывает те ошибки, которые проходят мимо ваших моков.
·>Если оно это показывает случайно, через несколько часов — то это называется хрень, а не показания.
Это намного лучше, чем их отсутствие.
P>> Они показывают, что приложение склеено как положено.
·>Это и проблема твоего подхода — у тебя в приложении на строчку кода ведро клея, который никак и не тестируется, кроме как тонной e2e.
Обратите внимание — сколько бы я вам ни говорил про юнит-тесты и интеграционные, вы всё равно видите своё.
Я даже цифры привел
Еще раз
e2e — меньше всего, десятки
интеграционные, функциональные — x10..x100 раз больше чем e2e
юнит-тесты, компонентные — x10..x100 раз больше, чем интеграционных
Вы выбросили:
верхний уровень — долго,
нижний — это "детали реализации"
Сверх этого кастрировали средний уровень и получили полуинтеграционные на моках
Итого — от вашей пирамиды остался поясок стыдливости
P>>Ну да — вы забили на интеграционные тесты.
·>Ну так в моём подходе этой интеграции кот наплакал, поэтому "приложение не упало при старте" уже практически означает, что 100% тех ошибок, "которые проходят мимо ваших моков" показано.
Это иллюзия. В сложном приложении интеграция не может быть простой, по определению.
Если у вас есть несколько источников данных для времени, то нужно гарантировать, что все они прописаны корректно для соответствующих юз кейсов
Как это проверяется стартом приложения — не ясно.
P>>·>Не годится. Мы не можем релизиться только с тремя десятками сценариев. Надо проверять 100%.
P>>Я ж вам не предлагаю выбросить — я вам предлагаю добавить, и показываю, как именно.
·>Добавлять тест, который запускается рандомно через раз — это какое-то извращение. Если некий тест запускать не обязательно для релиза, клиенты переживут и так — накой его вообще запускать?
Вы и запускаете его для релиза — только результаты собираете не разово, а в течение первых часов после деплоя.
Здесь важно обнаружить проблемы раньше юзеров на проде.
Очевидно, что если собирать сведения не раз. а несколько часов, то сведений будет больше, и диагностика будет точнее
P>>Вы уже релизитесь без 99%. Если к вашим тестами добавите e2e, то покрытие станет плотнее.
·>Не станет.
e2e регулярно находят проблемы которые другими тестам даже обнаружить сложно.
P>>Если не хватает времени — e2e можно гонять и после деплоймента, хоть круглые сутки, они хлеба не просят.
·>Зачем? Если они что-то обнаружат, это значит что у клиентов проблемы прямо сейчас, prod incident. Поздно борожоми пить.
Затем, что бы
1 обнаружить на самых ранних этапах
2 сразу собрать максимальное количество сведений. По этим тестам у вас больше всего сведений, как и что воспроизвестир
3 e2e репортает все найденные проблемы
Юзеры
1 репортают проблемы не сразу, а с большой задержкой
2 репортают не все сведения, а часто еще и лишних подкидывают
3 большинство вообще ничего не репортает, по разным причинам — к вам попадает ничтожная часть
Итого — разница 3:0 в пользу e2e
P>>Вы уже это делаете. e2e всего то сделают видимыми проблемы в тех 99% которые ходили мимо ваших моков.
·>Ещё раз. Если ты догадался нечто описать в виде теста, пусть e2e — это значит какой-то вполне определённый известный сценарий. Всегда есть возможность покрыть этот сценарий покрыть более дешёвыми тестами и выполнять до релиза, всегда, а не по броску монеты.
Сценарии и так покрыты дешовыми тестами. Эти дешовые тесты, особенно на моках, не покрывают всю интеграцию, что очевидно.
См пример сценария выше.
P>>Это способ выполнять те тесты, которые у вас вообще отсутствуют.
·>Потому что нахрен не нужны.
Вот это ваш самый частый аргумент вместе с "словоблудие" итд
P>>Вы тестируете минимально, репозиторий + бд. Эта часть есть и у меня.
·>Где конкретно эта часть есть у тебя? Ты заявлял, что в твоих pattern-тестах ты репозиторий + бд не тестируешь; а в e2e ты каждую переменную на null тестирвать не будешь, да и не сможешь.
Там же где и у вас — это часть интеграционных тестов.
P>>Комбинации различных условий в фильтре, что дает нам ту самую data complexity, и проблемные комбинации вы будете узнавать только на проде, одну за другой
·>Ты тоже.
Именно. И я этим знанием пользуюсь, а вы — нет. например, я точно знаю, как выглядит проблема с фильтрами — вгружается вообще всё. Соответсвенно вариантов решения у меня несколько
Даже если я не знаю комбинации, то могу подстараховаться пост-условием
А что бы пост-условие не потерялось, подкидываю тест
·>Причём тут текущее время? Проблема как раз была в том, что ты называешь "нефункциональные требования": "ну юзер же создался, а что ещё не совсем до конца создался, ничего страшного..".
Именно это нефункциональные требования и описывают — когда именно произойдет событие "юзер создался до конца". Вот здесь как правило запас по времени существенный.
Чем вы и пользуетесь для изменения дизайна.
P>>Вот-вот. И если BA даёт добро — всё хорошо.
·>Ну вот это "добро" тебе и надо будет выразить в тестах.
Разумеется.
P>>Уже в который раз уточняю, но вы всё равно видите чтото свое
·>В прыжке переобуваешься. Это совершенно не то, что ты изначально утверждал "БЛ начала вызываться через очередь, с задержкой от часов до дней". Написал "БЛ", а на самом деле телепатировал, есть части логики нужные сейчас, а есть части не сейчас. Если ты не понимаешь как это выражается с моками, задавай вопросы, а не фантазируй проблемы.
Что вас смущает? БЛ вызывается из разных мест приложения. Ключевое — консистентность тех или иных сведений.
P>>·>Из слов "паттерн тестируется" неясно кем.
P>>Если руками, что следует из выделеного, то какие варианты?
·>Мде, отстой.
Расскажите, как лучше. Желательно на тех самых фильтрах — откуда возьмете первый вариант запроса к бд, орм, нужное-вписать, и как будете его тестировать
P>>Я вам выделил, что бы виднее было.
·>Что за тест "против бд минимально заполненой под задачу"? Какие части системы он тестирует? e2e? или связка репо+бд? Или ещё что?
В зависимости от конкретного дизайна:
репозиторий + бд — если все запросы генерируются самим репозиторием
юз-кейс + репозиторий + бд — если у нас генерация выражений находится вне репозитория
P>>Не работает — вы не знаете проблемной комбинации для фильтров. Знаете только что они есть и их хрензнаетсколькилион
·>Комбинация ровно та же — что и в твоём тесте. Тест почти такой же — только вместо деталей реализации ассертится поведение.
Что вы будете ассертить в поведении?
P>>Что бы исключить ту самую проблему в явном виде — потенциальная загрузка всего содержимого таблицы.
·>Эта проблема не исключается тестом, как бы тебе это ни хотелось.
И давно у вас пост-условие стало тестом ?
P>>Покрывается. Я ж вам показал. Только решение и покрытие это разные вещи. В данном случае решение — постусловие. А тестами фиксируем, что бы не убежало
·>Что значит "не убежало"?
Пришел некто резкий и дерзкий и фиксанул "тут всё просто, я быстро". На его тестовой бд записей 60 штук, мелочовочка. А на проде это десятки миллионов.
P>>Покажите пример регрессии, которая не будет обнаружена этим тестом.
·>Ну загрузится пол таблицы.
Полтаблицы это 20 записей? Не понял, что за кейс такой.
> Или банально твой .top(10) не появится для какой-то конкретной комбинации фильтров, т.к. для этой комбинации решили немного переписать кусочек кода и забыли засунуть .top(10).
Что значит не появится? Если это пост-условие,оно будет применено для всего выхлопа, а не для разных подветок в вычислениях.
P>>Необязательно. Если я руками пишу весь запрос — то будет в коде явно. но запрос может и билдер создать.
·>Магически что-ли? Билдер рандомно top(10) не вставит, будет некий кусок кода который его ставит.
Поскольку билдер сложный, то можно сказать, что да, магически — прямой связи входа и выхода вы на глазок не обнаружите. Потому и надо подстраховываться в тестах.
P>>Некоторые детали нужно фиксировать в тестах, что бы случайно залетевший дятел не разрушил цивилизацию.
·>Дятлы тесты тоже умеют редактировать.
Умеют — здесь только код-ревью может помочь. О чем я вам и говорю в который раз.
> А с учётом того, что у тебя в тестах полный текст sql — то это будет простой copy-paste и вечнозелёный тест. А на ревью определить корректность sql на вид могут не только лишь все.
В данном случае и не нужно, что бы все могли определять корректность — код заведомо нетривиальный.
P>>Решение — пост-условие. А вот тест который я показал, он всего то гарантирует сохранность этого пост-условия.
·>Не гарантирует.
Видите — снова без аргументов, голословно
P>>Если вы не можете сделать этого руками, то ваши попытки выразить это в коде и генерации данных будут иметь ту же особенность.
·>Ты не понял. Я могу сделать это не руками, а кодом.
Для простых фильров это работает. Для сложных — проще найти решение напрямую, в бд, что бы представлять, куда всё двигать
P>>Есть и такие — их проще писать сразу, проще отдладить по горячим следам.
P>>Но с ростом сложности приходится вводить дополнительные инструменты.
·>Это где ты говорил такое месяц назад? Цитату.
Вам не только я, но и Синклер это же сказал.
P>>Пост-условия похоже для вас пустой звук, вам это всё равно кажется тестом. Тест всего лишь гарантирует сохранность пост-условия
·>Не гарантирует.
У вас похоже тесты вообще ничего не гарантируют. Зачем же вы их пишете?
P>>И решения и у меня, и у вас, для подобных кейсов будут одни и те же.
·>Ну может быть колонок id несколько разных и иногда они совпадают... но не всегда.
каким образом в одной таблице users может быть несколько колонок id ? byId — это запрос к праймари кей. Ломается только если схема поломана.
P>>Вы снова чего то фантазируете.
·>Что фантазирую? Это вроде ты предлагаешь в код вставлять top(10) и тестом "фиксировать".
Это же пост-условие.
P>>Нет, не могут. Так, как это утверждает т. Райса — вы true от false отличить не сможете. Можете потренироваться — тестами обнаружить функцию, которая всегда возвращает true. Валяйте.
·>"всегда" — это уже нетривиальное свойство. Проверка тривиального свойства это по сути "выполнить код и поглядеть на результат", т.е. тест практически.
Ловко вы опровергли теорему Райса!
В т.Райса нетривиальное свойство означает, что есть функции, которые им обладают, а есть те, которые не обладают.
То есть, искать разницу между двумя функциями вы будете до скончания времён
P>>Как наиграетесь, приходите
·>Не понял. Да, эта функция возвращает true. Тестом будет "f=() -> true; assertTrue(f())".
Вот-вот. Опровержение теоремы Райса! Ну Нобелевка же!
P>>Смотрите выше, текст выделен H1, как раз эту вашу способность и "демонстрирует"
·>Так ещё до того как ты это написал уже говорил, что _необходимость_ ручного тестирования — проблема. Не надо так делать и рассказал как избежать эту необходимость.
Ручное тестирование плохо не само по себе, а когда оно увеличивает время разработки
В данном случае мы ищем решение — потому и тестируем руками, т.к. запрос ни разу не тривиальный и нужно быстро перебрать десяток другой вариантов.
Это намного быстрее чем делать то же самое кодом к orm или билдером запросов.
В тривиальный случаях, типа "user.byId()" ровно наоборот — быстрее именно кодом
P>>Хрупкий — это я вам сразу сказал.
Я снова выделил, что бы вам виднее было. Посимвольно это потому, что у меня в конкретном случае нет ни json, ни orm, ни еще какого ast.
deep.eq дает нам вполне годную структурную эквивалентность.
Если вы ей не умеете пользоваться — значит это не ваш вариант
P>>Да то, что искать тестами проблемные комбинации вы вспотеете. Нужно искать решение вне тестов.
·>Ясен пень, тестами комбинации не ищутся, а тестируются. Анализируешь код, coverage report, логи, спеки и т.п., потом пишешь тест подозрительной комбинации и смотришь как себя система ведёт.
И так будете для каждой комбинации, да? Дадите шанс юзеру убиться об ваш билдер фильтров?
P>>Ну можете не руками, а попросить того, кто знает схему бд и язык запросов к ней.
·>А этот кто-то как будет, ногами что-ли?
·>Ок, допустим ногами. А какие в базе будут данные на которой этот чаи-гпт будет проверять свои запросы вножную? За 2025 год, правильно?
Жалко, что нет шрифта больше чем h1
сначала руками, а потом тестом против бд минимально заполненой под задачу
P>>Почему первые запуски — потому, что после них как раз будет известен паттерн, по которому нужно будет строить запросы. дальше в ручных проверках смысла не много.
·>Потом система меняется и паттерн перестаёт функционировать проверенным вручную способом, а тестам — пофиг, они вечнозелёные.
А интеграционные тесты вы забыли, да?
Мне что, каждую строчку теперь H1 выделять, что бы вам виднее было?
P>>С фильтрами комбинаций столько, что солнце погаснет раньше ваших тестов.
·>Даже если и так, то до e2e-комбинаций и жизни Вселенной не хватит уж точно.
В том то и дело — количество e2e никак не зависит от количества комбинаций в фильтрах.
P>>Проблема в том, что бы генерить данные, нужно знать комбинации которые будут проблемными.
·>Это же требуется и для того чтобы чтобы руками проверять запросы.
Похоже, пост-условия для вас пустой звук. Для моего варианта нужно проверить,
1 работает ли пост-условие
2 находится ли оно на своем месте
3 все ли ветки ифов получат его
Вот это — решение. А тестами фиксируем сохранность этого условия. Т.е. тесты это второстепенная роль в данном случае.
P>>моки и конформационные тесты это не решение, а компенсация.
·>Способ экономии ресурсов.
Имено — за счет покрытия.
P>>Вы отказываетесь идти дальше, и делать внятное покрытие e2e, и посмеиваетесь с тех, кто всё таки покрывает эти 99% как следует.
·>Скорее завидую простоте системы, что её реально покрыть e2e на 99%.
Вы сами себя ограбили когда строили вашу пирамиду тестов в виде трапеции — полуинтеграционные на моках + конформанс, которые к вашей системе имеют слабое отношение.
P>>Пример у вас есть внятный? Мне непонятно, каким чудом моки репозитория помогут понять, что же с интеграцией не так.
·>Они не для этого.
В том то и дело — вы оставили себе только полуинтеграционные тесты на моках.
Юнит-тесты вы не пишете, т.к. "это детали реализации, их не надо писать"
e2e "слишком долго"
P>>Какой компоент системы вы собираетесь конф тестами покрывать?
·>Конф-тесты тестируют чужое api. Система (по крайней мере её прод-часть) не принимает участие в конф-тестах.
Про то и речь — про интеграцию ваших компонентов с другими вашими же компонентами они ничего не говорят.
P>>Расскажите внятно, как мок репозитория поможет вам с интеграцией уровня приложения?
·>Никак. Мок поможет тестировать часть приложения с меньшим количеством ресурсов, следовательно позволит иметь больше покрытых сценариев.
В сценариях нас интересует интеграция прежде всего.
Например — юзер регистрируется, уточняет сведения, подтверждает регистрацию, делает N действий, смотрит в аудит, все ли хорошо, и делает логаут.
Итого:
Данные от входного запроса POST /users будут передаваться как положено во все части системы, и обратно, и это будет отражено везде — в профайле юзера, во всех частях админке
А далее, апдейт того же юзера снова даст ожидаемый результат и в профайле, и во всех частях админки
И так со всеми действиями согласно сценарию до самого последнего.
Если вы моками нарезали весь этот путь на части, вы знаете, что внутри каждой из частей всё хорошо
А вот склейку всех частей тестируют тесты системного уровня, например, те самые e2e
P>>Наоборот, e2e показывает те ошибки, которые проходят мимо ваших моков.
·>Если оно это показывает случайно, через несколько часов — то это называется хрень, а не показания.
Это намного лучше, чем их отсутствие.
P>> Они показывают, что приложение склеено как положено.
·>Это и проблема твоего подхода — у тебя в приложении на строчку кода ведро клея, который никак и не тестируется, кроме как тонной e2e.
Обратите внимание — сколько бы я вам ни говорил про юнит-тесты и интеграционные, вы всё равно видите своё.
Я даже цифры привел
Еще раз
e2e — меньше всего, десятки
интеграционные, функциональные — x10..x100 раз больше чем e2e
юнит-тесты, компонентные — x10..x100 раз больше, чем интеграционных
Вы выбросили:
верхний уровень — долго,
нижний — это "детали реализации"
Сверх этого кастрировали средний уровень и получили полуинтеграционные на моках
Итого — от вашей пирамиды остался поясок стыдливости
P>>Ну да — вы забили на интеграционные тесты.
·>Ну так в моём подходе этой интеграции кот наплакал, поэтому "приложение не упало при старте" уже практически означает, что 100% тех ошибок, "которые проходят мимо ваших моков" показано.
Это иллюзия. В сложном приложении интеграция не может быть простой, по определению.
Если у вас есть несколько источников данных для времени, то нужно гарантировать, что все они прописаны корректно для соответствующих юз кейсов
Как это проверяется стартом приложения — не ясно.
P>>·>Не годится. Мы не можем релизиться только с тремя десятками сценариев. Надо проверять 100%.
P>>Я ж вам не предлагаю выбросить — я вам предлагаю добавить, и показываю, как именно.
·>Добавлять тест, который запускается рандомно через раз — это какое-то извращение. Если некий тест запускать не обязательно для релиза, клиенты переживут и так — накой его вообще запускать?
Вы и запускаете его для релиза — только результаты собираете не разово, а в течение первых часов после деплоя.
Здесь важно обнаружить проблемы раньше юзеров на проде.
Очевидно, что если собирать сведения не раз. а несколько часов, то сведений будет больше, и диагностика будет точнее
P>>Вы уже релизитесь без 99%. Если к вашим тестами добавите e2e, то покрытие станет плотнее.
·>Не станет.
e2e регулярно находят проблемы которые другими тестам даже обнаружить сложно.
P>>Если не хватает времени — e2e можно гонять и после деплоймента, хоть круглые сутки, они хлеба не просят.
·>Зачем? Если они что-то обнаружат, это значит что у клиентов проблемы прямо сейчас, prod incident. Поздно борожоми пить.
Затем, что бы
1 обнаружить на самых ранних этапах
2 сразу собрать максимальное количество сведений. По этим тестам у вас больше всего сведений, как и что воспроизвестир
3 e2e репортает все найденные проблемы
Юзеры
1 репортают проблемы не сразу, а с большой задержкой
2 репортают не все сведения, а часто еще и лишних подкидывают
3 большинство вообще ничего не репортает, по разным причинам — к вам попадает ничтожная часть
Итого — разница 3:0 в пользу e2e
P>>Вы уже это делаете. e2e всего то сделают видимыми проблемы в тех 99% которые ходили мимо ваших моков.
·>Ещё раз. Если ты догадался нечто описать в виде теста, пусть e2e — это значит какой-то вполне определённый известный сценарий. Всегда есть возможность покрыть этот сценарий покрыть более дешёвыми тестами и выполнять до релиза, всегда, а не по броску монеты.
Сценарии и так покрыты дешовыми тестами. Эти дешовые тесты, особенно на моках, не покрывают всю интеграцию, что очевидно.
См пример сценария выше.
P>>Это способ выполнять те тесты, которые у вас вообще отсутствуют.
·>Потому что нахрен не нужны.
Вот это ваш самый частый аргумент вместе с "словоблудие" итд
P>>Вы тестируете минимально, репозиторий + бд. Эта часть есть и у меня.
·>Где конкретно эта часть есть у тебя? Ты заявлял, что в твоих pattern-тестах ты репозиторий + бд не тестируешь; а в e2e ты каждую переменную на null тестирвать не будешь, да и не сможешь.
Там же где и у вас — это часть интеграционных тестов.
P>>Комбинации различных условий в фильтре, что дает нам ту самую data complexity, и проблемные комбинации вы будете узнавать только на проде, одну за другой
·>Ты тоже.
Именно. И я этим знанием пользуюсь, а вы — нет. например, я точно знаю, как выглядит проблема с фильтрами — вгружается вообще всё. Соответсвенно вариантов решения у меня несколько
Даже если я не знаю комбинации, то могу подстараховаться пост-условием
А что бы пост-условие не потерялось, подкидываю тест
·>Причём тут текущее время? Проблема как раз была в том, что ты называешь "нефункциональные требования": "ну юзер же создался, а что ещё не совсем до конца создался, ничего страшного..".
Именно это нефункциональные требования и описывают — когда именно произойдет событие "юзер создался до конца". Вот здесь как правило запас по времени существенный.
Чем вы и пользуетесь для изменения дизайна.
P>>Вот-вот. И если BA даёт добро — всё хорошо.
·>Ну вот это "добро" тебе и надо будет выразить в тестах.
Разумеется.
P>>Уже в который раз уточняю, но вы всё равно видите чтото свое
·>В прыжке переобуваешься. Это совершенно не то, что ты изначально утверждал "БЛ начала вызываться через очередь, с задержкой от часов до дней". Написал "БЛ", а на самом деле телепатировал, есть части логики нужные сейчас, а есть части не сейчас. Если ты не понимаешь как это выражается с моками, задавай вопросы, а не фантазируй проблемы.
Что вас смущает? БЛ вызывается из разных мест приложения. Ключевое — консистентность тех или иных сведений.
P>>·>Из слов "паттерн тестируется" неясно кем.
P>>Если руками, что следует из выделеного, то какие варианты?
·>Мде, отстой.
Расскажите, как лучше. Желательно на тех самых фильтрах — откуда возьмете первый вариант запроса к бд, орм, нужное-вписать, и как будете его тестировать
P>>Я вам выделил, что бы виднее было.
·>Что за тест "против бд минимально заполненой под задачу"? Какие части системы он тестирует? e2e? или связка репо+бд? Или ещё что?
В зависимости от конкретного дизайна:
репозиторий + бд — если все запросы генерируются самим репозиторием
юз-кейс + репозиторий + бд — если у нас генерация выражений находится вне репозитория
P>>Не работает — вы не знаете проблемной комбинации для фильтров. Знаете только что они есть и их хрензнаетсколькилион
·>Комбинация ровно та же — что и в твоём тесте. Тест почти такой же — только вместо деталей реализации ассертится поведение.
Что вы будете ассертить в поведении?
P>>Что бы исключить ту самую проблему в явном виде — потенциальная загрузка всего содержимого таблицы.
·>Эта проблема не исключается тестом, как бы тебе это ни хотелось.
И давно у вас пост-условие стало тестом ?
P>>Покрывается. Я ж вам показал. Только решение и покрытие это разные вещи. В данном случае решение — постусловие. А тестами фиксируем, что бы не убежало
·>Что значит "не убежало"?
Пришел некто резкий и дерзкий и фиксанул "тут всё просто, я быстро". На его тестовой бд записей 60 штук, мелочовочка. А на проде это десятки миллионов.
P>>Покажите пример регрессии, которая не будет обнаружена этим тестом.
·>Ну загрузится пол таблицы.
Полтаблицы это 20 записей? Не понял, что за кейс такой.
> Или банально твой .top(10) не появится для какой-то конкретной комбинации фильтров, т.к. для этой комбинации решили немного переписать кусочек кода и забыли засунуть .top(10).
Что значит не появится? Если это пост-условие,оно будет применено для всего выхлопа, а не для разных подветок в вычислениях.
P>>Необязательно. Если я руками пишу весь запрос — то будет в коде явно. но запрос может и билдер создать.
·>Магически что-ли? Билдер рандомно top(10) не вставит, будет некий кусок кода который его ставит.
Поскольку билдер сложный, то можно сказать, что да, магически — прямой связи входа и выхода вы на глазок не обнаружите. Потому и надо подстраховываться в тестах.
P>>Некоторые детали нужно фиксировать в тестах, что бы случайно залетевший дятел не разрушил цивилизацию.
·>Дятлы тесты тоже умеют редактировать.
Умеют — здесь только код-ревью может помочь. О чем я вам и говорю в который раз.
> А с учётом того, что у тебя в тестах полный текст sql — то это будет простой copy-paste и вечнозелёный тест. А на ревью определить корректность sql на вид могут не только лишь все.
В данном случае и не нужно, что бы все могли определять корректность — код заведомо нетривиальный.
P>>Решение — пост-условие. А вот тест который я показал, он всего то гарантирует сохранность этого пост-условия.
·>Не гарантирует.
Видите — снова без аргументов, голословно
P>>Если вы не можете сделать этого руками, то ваши попытки выразить это в коде и генерации данных будут иметь ту же особенность.
·>Ты не понял. Я могу сделать это не руками, а кодом.
Для простых фильров это работает. Для сложных — проще найти решение напрямую, в бд, что бы представлять, куда всё двигать
P>>Есть и такие — их проще писать сразу, проще отдладить по горячим следам.
P>>Но с ростом сложности приходится вводить дополнительные инструменты.
·>Это где ты говорил такое месяц назад? Цитату.
Вам не только я, но и Синклер это же сказал.
P>>Пост-условия похоже для вас пустой звук, вам это всё равно кажется тестом. Тест всего лишь гарантирует сохранность пост-условия
·>Не гарантирует.
У вас похоже тесты вообще ничего не гарантируют. Зачем же вы их пишете?
P>>И решения и у меня, и у вас, для подобных кейсов будут одни и те же.
·>Ну может быть колонок id несколько разных и иногда они совпадают... но не всегда.
каким образом в одной таблице users может быть несколько колонок id ? byId — это запрос к праймари кей. Ломается только если схема поломана.
P>>Вы снова чего то фантазируете.
·>Что фантазирую? Это вроде ты предлагаешь в код вставлять top(10) и тестом "фиксировать".
Это же пост-условие.
P>>Нет, не могут. Так, как это утверждает т. Райса — вы true от false отличить не сможете. Можете потренироваться — тестами обнаружить функцию, которая всегда возвращает true. Валяйте.
·>"всегда" — это уже нетривиальное свойство. Проверка тривиального свойства это по сути "выполнить код и поглядеть на результат", т.е. тест практически.
Ловко вы опровергли теорему Райса!
В т.Райса нетривиальное свойство означает, что есть функции, которые им обладают, а есть те, которые не обладают.
То есть, искать разницу между двумя функциями вы будете до скончания времён
P>>Как наиграетесь, приходите
·>Не понял. Да, эта функция возвращает true. Тестом будет "f=() -> true; assertTrue(f())".
Вот-вот. Опровержение теоремы Райса! Ну Нобелевка же!
P>>Смотрите выше, текст выделен H1, как раз эту вашу способность и "демонстрирует"
·>Так ещё до того как ты это написал уже говорил, что _необходимость_ ручного тестирования — проблема. Не надо так делать и рассказал как избежать эту необходимость.
Ручное тестирование плохо не само по себе, а когда оно увеличивает время разработки
В данном случае мы ищем решение — потому и тестируем руками, т.к. запрос ни разу не тривиальный и нужно быстро перебрать десяток другой вариантов.
Это намного быстрее чем делать то же самое кодом к orm или билдером запросов.
В тривиальный случаях, типа "user.byId()" ровно наоборот — быстрее именно кодом
P>>Хрупкий — это я вам сразу сказал.
Так я ж и не предлагаю посимвольное сравнение на все случаи жизни.
·>deep.eq по-другому тупо не умеет.Я снова выделил, что бы вам виднее было. Посимвольно это потому, что у меня в конкретном случае нет ни json, ни orm, ни еще какого ast.
deep.eq дает нам вполне годную структурную эквивалентность.
Если вы ей не умеете пользоваться — значит это не ваш вариант
P>>Да то, что искать тестами проблемные комбинации вы вспотеете. Нужно искать решение вне тестов.
·>Ясен пень, тестами комбинации не ищутся, а тестируются. Анализируешь код, coverage report, логи, спеки и т.п., потом пишешь тест подозрительной комбинации и смотришь как себя система ведёт.
И так будете для каждой комбинации, да? Дадите шанс юзеру убиться об ваш билдер фильтров?
P>>Ну можете не руками, а попросить того, кто знает схему бд и язык запросов к ней.
·>А этот кто-то как будет, ногами что-ли?
·>Ок, допустим ногами. А какие в базе будут данные на которой этот чаи-гпт будет проверять свои запросы вножную? За 2025 год, правильно?
Жалко, что нет шрифта больше чем h1
сначала руками, а потом тестом против бд минимально заполненой под задачу
P>>Почему первые запуски — потому, что после них как раз будет известен паттерн, по которому нужно будет строить запросы. дальше в ручных проверках смысла не много.
·>Потом система меняется и паттерн перестаёт функционировать проверенным вручную способом, а тестам — пофиг, они вечнозелёные.
А интеграционные тесты вы забыли, да?
Мне что, каждую строчку теперь H1 выделять, что бы вам виднее было?
P>>С фильтрами комбинаций столько, что солнце погаснет раньше ваших тестов.
·>Даже если и так, то до e2e-комбинаций и жизни Вселенной не хватит уж точно.
В том то и дело — количество e2e никак не зависит от количества комбинаций в фильтрах.
P>>Проблема в том, что бы генерить данные, нужно знать комбинации которые будут проблемными.
·>Это же требуется и для того чтобы чтобы руками проверять запросы.
Похоже, пост-условия для вас пустой звук. Для моего варианта нужно проверить,
1 работает ли пост-условие
2 находится ли оно на своем месте
3 все ли ветки ифов получат его
Вот это — решение. А тестами фиксируем сохранность этого условия. Т.е. тесты это второстепенная роль в данном случае.