Здравствуйте, Pauel, Вы писали:
P>>>Будут. Но их всё равно нужно делать, т.к. никакие другие виды тестов их не заменяют, только кое где могут скомпенсировать.
P>·>Нужно, но как-то всё равно придётся покрывать остальные 99%. Вот тут и приходят на помощь моки и конф-тесты.
P>И вам всё еще непонятно, почему люди на проде тестируют?
Потому что могут (с)
P>моки и конформационные тесты это не решение, а компенсация.
Способ экономии ресурсов.
P>Вы отказываетесь идти дальше, и делать внятное покрытие e2e, и посмеиваетесь с тех, кто всё таки покрывает эти 99% как следует.
Скорее завидую простоте системы, что её реально покрыть e2e на 99%.
P>>>Если у вас сложный воркфлоу, то его нечем протестировать, кроме вот этих e2e
P>·>Я тебе уже рассказал чем: моки и конф-тесты.
P>Пример у вас есть внятный? Мне непонятно, каким чудом моки репозитория помогут понять, что же с интеграцией не так.
Они не для этого.
P>Какой компоент системы вы собираетесь конф тестами покрывать?
Конф-тесты тестируют чужое api. Система (по крайней мере её прод-часть) не принимает участие в конф-тестах.
P>>>Не могут — моки по своей сути подменяют интеграцию отсебятиной.
P>·>Не только моки, но конф-тесты. Плюс соответствующий дизайн и процесс разработки.
P>Расскажите внятно, как мок репозитория поможет вам с интеграцией уровня приложения?
Никак. Мок поможет тестировать часть приложения с меньшим количеством ресурсов, следовательно позволит иметь больше покрытых сценариев.
P>>>Итого, с ваших слов "задача сложная, нахер e2e, будем моки писать и сделаем вид, что это равноценная замена"
P>·>Не "нахер e2e", а "хрень получается с e2e".
P>Наоборот, e2e показывает те ошибки, которые проходят мимо ваших моков.
Если оно это показывает случайно, через несколько часов — то это называется хрень, а не показания.
P> Они показывают, что приложение склеено как положено.
Это и проблема твоего подхода — у тебя в приложении на строчку кода ведро клея, который никак и не тестируется, кроме как тонной e2e.
P>>>1 Аксиома — количество юнит-тестов и полуинтеграционных на моках никак не влияет на количество e2e. Никак, нисколько!
P>·>Тавтология. Я говорю о другом: количество e2e ограничивается доступными ресурсами. Чем меньше доступных e2e, тем больше приходится вкладываться в юнит и "полуинтеграционные".
P>Ну да — вы забили на интеграционные тесты.
Ну так в моём подходе этой интеграции кот наплакал, поэтому "приложение не упало при старте" уже практически означает, что 100% тех ошибок, "которые проходят мимо ваших моков" показано.
P>>> юниты и ваши полуинтеграционные пишите сколько надо, что бы быстро детектить мелочевку во время разработки
P>>>2 e2e можно сделать так -
P>>>- при билде — три самых частых
P>>>- при деплое — три десятка самых частых
P>>>- после деплоя — всё вместе, рандомно, то одно, то другое, с таким расчетом, что бы за день вы получили сведения что где может отвалиться
P>·>Не годится. Мы не можем релизиться только с тремя десятками сценариев. Надо проверять 100%.
P>Я ж вам не предлагаю выбросить — я вам предлагаю добавить, и показываю, как именно.
Добавлять тест, который запускается рандомно через раз — это какое-то извращение. Если некий тест запускать не обязательно для релиза, клиенты переживут и так — накой его вообще запускать?
P>Вы уже релизитесь без 99%. Если к вашим тестами добавите e2e, то покрытие станет плотнее.
Не станет.
P>Если не хватает времени — e2e можно гонять и после деплоймента, хоть круглые сутки, они хлеба не просят.
Зачем? Если они что-то обнаружат, это значит что у клиентов проблемы прямо сейчас, prod incident. Поздно борожоми пить.
P>>>Итого — ваши 99% кейсов вы будете тестировать после деплоя. Боитесь делать это на проде — делайте на стейдже, деве и тд.
P>·>Не можем мы деплоить продукт оттестированный на 1%.
P>Вы уже это делаете. e2e всего то сделают видимыми проблемы в тех 99% которые ходили мимо ваших моков.
Ещё раз. Если ты догадался нечто описать в виде теста, пусть e2e — это значит какой-то вполне определённый известный сценарий. Всегда есть возможность покрыть этот сценарий покрыть более дешёвыми тестами и выполнять до релиза, всегда, а не по броску монеты.
P>>>3. каждые N минут запускаете `curl <stage>/manifest.test | run-test --random --url <stage>`
P>·> Т.е. качество продукта проверяем случайно. Это только для хоумпейджей годится.
P>Это способ выполнять те тесты, которые у вас вообще отсутствуют.
Потому что нахрен не нужны.
P>>>Это полные тесты, где всё тащится медленно и реально — они нужны и вам, и мне. Если вы не учли этот кейс с нулём, то будет проблема. Ровно так же и у меня.
P>·>Ясен пень. Ты вообще читаешь что я пишу? Суть в том, что даже если вы учли кейс с нулём, то у вас всё равно будет проблема, а нас проблемы не будет.
P>Непонятно — как X может быть больше чем X + Y если и X и Y больше нуля?
P>Вы тестируете минимально, репозиторий + бд. Эта часть есть и у меня.
Где конкретно эта часть есть у тебя? Ты заявлял, что в твоих pattern-тестах ты репозиторий + бд не тестируешь; а в e2e ты каждую переменную на null тестирвать не будешь, да и не сможешь.
P>Извините, но вы или не читаете, или вас чтото не то с логикой.
Я читаю что ты мне пишешь.
P>>>И задача с фильтрами это про комбинации
P>·>Может я не понял твою задачу правильно, но в моём понимании, фильтры это задача которая сводится к одному компоненту, который может быть протестирован отдельно, а не комбинации различных компонент
P>Комбинации различных условий в фильтре, что дает нам ту самую data complexity, и проблемные комбинации вы будете узнавать только на проде, одну за другой
Ты тоже.
P>Собственно из за того, что никто вам заранее не выдал список проблемных комбинаций, нужно "придётся выдумывать правильную архитектуру и подходы контроля качества, чтобы риск неизвестного минимизировать"
Ну да. А что делать? Не всем так везёт, как в твоём хоумпейдже: тебе сразу выдали список проблемных комбинаций, так что в твоём случае всё равно, хоть левой пяткой тестируй, а клиентам пофиг на сломаный код в проде — все подходы работают.
P>>>>>Я такого не говорил — это вы начали фантазировать, что придется ждать 5 минут и никак иначе не выйдет. Обоснования у вас никакого нет.
P>>>·>Про 5 минут я не фантазировал, это твоя цитата.
P>>>Я нигде не говорил, что юзер должен ждать 5 минут. Даже если профиль создаётся неделю, редактировать данные можно сразу.
P>·>Говорил, цитирую: чудесные вещи типа "после того, как сделал var u = service.CreateUser(...), нужно выждать не менее 5 минут перед service.UpdateUser(u, ...)".
P>Вы или поиском пользоваться не умеете, или запомнить трудно.
Да, ошибся, см. ответы с Синклером сегодня.
P>Синклер привел пример "А в реальных системах встречаются ещё и чудесные вещи типа "после того, как сделал var u = service.CreateUser(...), нужно выждать не менее 5 минут перед service.UpdateUser(u, ...)", с которыми совсем всё плохо." И пример был про то, откуда берется время "задним числом"
Перечитай. Проблема была не со временем, а с синхронизацией действий.
P>Можно ли нажимать конопку, нельзя — у Синклера пример про то откуда будет браться время отличное от текущего.
Причём тут текущее время? Проблема как раз была в том, что ты называешь "нефункциональные требования": "ну юзер же создался, а что ещё не совсем до конца создался, ничего страшного..".
P>>>Вам нужно спросить у BA, какие данные надо сейчас, а какие — вообще.
P>·>Именно — вопросы за которые отвечает BA — это функциональные требования по сути.
P>Вот-вот. И если BA даёт добро — всё хорошо.
Ну вот это "добро" тебе и надо будет выразить в тестах.
P>·>У тебя есть бизнес-функция "создать юзера". Результат который возвращается из этой функции — это тоже функциональный элемент. Результат говорит о том, что что-то произошло. Если ты вместо того, чтобы сделать саму операцию кладёшь что-то в очередь, то и результат функции меняется — вместо "что-то произошло", будет "что-то произойдёт".
P>Не вместо, а вместе. Все что нужно для редактирования — возвращаем сразу, BA так сказал. Всё, что для редактирования не нужно — вообще не возвращаем. А раз так, то можем поступать как проще — можно сразу, можно потом.
P>Уже в который раз уточняю, но вы всё равно видите чтото свое
В прыжке переобуваешься. Это совершенно не то, что ты изначально утверждал "БЛ начала вызываться через очередь, с задержкой от часов до дней". Написал "БЛ", а на самом деле телепатировал, есть части логики нужные сейчас, а есть части не сейчас. Если ты не понимаешь как это выражается с моками, задавай вопросы, а не фантазируй проблемы.
P>>>Вы сами себе придумали какой то вариант, где сделано заведомо кривое решение, и теперь рассказываете будто это самый типичный случай.
P>·>Это не я придумал, это ты придумал.
P>Уже выяснили — это вы притянули пример Синклера который был совсем про другое.
Да, я перепутал. У Синклера было про 5 минут, а у тебя было часы-дни.
P>>>Зачем вам менять апишку для этого кейса?
P>·>Затем, что функция API "выполнить действие X" != "положить в очередь чтобы действие X когда-нибудь выполнилось (может быть)". Апишка просто обязана быть разной, чтобы не было таких "чудесных вещей", которые ты так любишь.
P>Вы путаете интерфейс и реализацию. API — create user, данные вернуть сразу — id, имя, фамилию. Всё не id-имя-фамилия, вы может создавать когда угодно, хоть с очередью, хоть без. Можете создать сразу — отлично. Не получается — ну и хрен с ним, абы id-имя-фамилия были дадены сразу
Это вы путаетесь в показаниях.
P>·>Из слов "паттерн тестируется" неясно кем.
P>Если руками, что следует из выделеного, то какие варианты?
Мде, отстой.
P>>>3. какими тестами
P>·>Из слов "паттерн тестируется" неясно какими тестами
P>Я вам выделил, что бы виднее было.
Что за тест "против бд минимально заполненой под задачу"? Какие части системы он тестирует? e2e? или связка репо+бд? Или ещё что?
P>>>1. что делаем — сравниваем посимвольно, т.к. другого варианта нет — на одну задачу пилить ast на алгебраических типах данных это овердохрена
P>·>Другой вариант я рассказал — выполнить запрос на базе и заасертить результат.
P>Не работает — вы не знаете проблемной комбинации для фильтров. Знаете только что они есть и их хрензнаетсколькилион
Комбинация ровно та же — что и в твоём тесте. Тест почти такой же — только вместо деталей реализации ассертится поведение.
P>>>2. для чего делаем — что бы зафиксировать паттерн
P>·>Зачем?
P>Что бы исключить ту самую проблему в явном виде — потенциальная загрузка всего содержимого таблицы.
Эта проблема не исключается тестом, как бы тебе это ни хотелось.
P>>>Вы до сих пор такой тест не показали
P>·>Это не покрывается тестами принципиально.
P>Покрывается. Я ж вам показал. Только решение и покрытие это разные вещи. В данном случае решение — постусловие. А тестами фиксируем, что бы не убежало
Что значит "не убежало"?
P>·>Только если у тебя какой-то очень частый случай и ты завязываешься на какую-то конкретную реализацию — а это значит, что у тебя тесты не будут тестировать даже регрессию.
P>Покажите пример регрессии, которая не будет обнаружена этим тестом.
Ну загрузится пол таблицы. Или банально твой .top(10) не появится для какой-то конкретной комбинации фильтров, т.к. для этой комбинации решили немного переписать кусочек кода и забыли засунуть .top(10).
P>·>Я никогда не просил объяснений, я просил код. Ибо по коду видны факты, а не твои фантазии. Так что не удивляйся, что твои объяснения являются словоблудием.
P>С кодом у вас два варианта
P>1. не будет работать
Так я объясняю почему не будет работать и как надо сделать чтобы работало.
P>>>Можно ограничить таблицы, из которых может или не может делаться джойн итд
P>·>Т.е. в тесте ты единственное что можешь зафиксировать, что в коде у тебя действительно стоит .top(10). И что? Зачем? Наличие .top(10) и так видно, оно уже и так явно прописано в коде.
P>Необязательно. Если я руками пишу весь запрос — то будет в коде явно. но запрос может и билдер создать.
Магически что-ли? Билдер рандомно top(10) не вставит, будет некий кусок кода который его ставит.
P>Некоторые детали нужно фиксировать в тестах, что бы случайно залетевший дятел не разрушил цивилизацию.
Дятлы тесты тоже умеют редактировать. А с учётом того, что у тебя в тестах полный текст sql — то это будет простой copy-paste и вечнозелёный тест. А на ревью определить корректность sql на вид могут не только лишь все.
P>>>Кто вам скажет, что в ваших этих 30 записях есть все потенциально опасные или невалидные комбинации?
P>·>Это не решается тестами, никакими.
P>Решение — пост-условие. А вот тест который я показал, он всего то гарантирует сохранность этого пост-условия.
Не гарантирует.
P>>>Вручную всё равно придется проверять, это обязательный этап — с этого всё начинается.
P>·>Почему обязательный?
P>Если вы не можете сделать этого руками, то ваши попытки выразить это в коде и генерации данных будут иметь ту же особенность.
Ты не понял. Я могу сделать это не руками, а кодом.
P>>>Эта часть же как и у вас. Это именно интеграционный тест репозитория.
P>·>Т.е. тест репо+бд? У вас есть и такие тесты?
P>Я вам уже который месяц говорю, что предлагаю добавить, а не выбросить.
P>Есть и такие — их проще писать сразу, проще отдладить по горячим следам.
P>Но с ростом сложности приходится вводить дополнительные инструменты.
Это где ты говорил такое месяц назад? Цитату.
P>>>Только сверх этого вы собираетесь и комбинации фильтров гонять здесь же. И на мой взгляд это совсем не то, чем нужно заниматься в этом виде тестов.
P>·>Потому что юнит-тесты побуквенного сравнения sql-текста практически бесполезны и даже вредны.
P>А разве я говорю, что это надо повсеместно?
Да нигде не надо.
P>>>Что будете в тест писать ?
P>·>В тесте по определению тестируется известное. Если ты считаешь твои тесты тестируют неизвестное — ты заблуждаешься.
P>Пост-условия похоже для вас пустой звук, вам это всё равно кажется тестом. Тест всего лишь гарантирует сохранность пост-условия
Не гарантирует.
P>>>Это же в операции известно, какие данные она возвращает. Если users.byId() то очевидно здесь один. А если users.where — вот тут а хрен его знает
P>·>Угу, именно, что "очевидно", но кто-то накосячил с фильтром в byId и у тебя внезапно не один... Т.е. если это и как-то проверяется, но не тестами.
P>Эта проблема и у вас будет. Например, вы тестируете на бд, где id это праймари кей, а в проде каким то чудом окажется другая схема, где id может иметь дубликаты
P>И решения и у меня, и у вас, для подобных кейсов будут одни и те же.
Ну может быть колонок id несколько разных и иногда они совпадают... но не всегда.
P>>>У вас что, в требованиях позволено сдыхать при процессинге?
P>·>http 4xx или 5xx. Везде тупо возвращать только первые 10 записей и делать вид что так и надо — это какая-то студенческя поделка.
P>Вы снова чего то фантазируете.
Что фантазирую? Это вроде ты предлагаешь в код вставлять top(10) и тестом "фиксировать".
P>>>И тут мы узнаем... что тестами ничо не сделаешь. Гы-гы.
P>·>Тесты могут проверять только тривиальные свойства.
P>Нет, не могут. Так, как это утверждает т. Райса — вы true от false отличить не сможете. Можете потренироваться — тестами обнаружить функцию, которая всегда возвращает true. Валяйте.
"всегда" — это уже нетривиальное свойство. Проверка тривиального свойства это по сути "выполнить код и поглядеть на результат", т.е. тест практически.
P>Как напишете ваш тест — кидайте сюда, а я покажу, какая фукнция проходит ваш тест и не удовлетворяет условию
P>Для простоты, функция будет такой — () -> true, т.к. никаких параметров и тд и тд и тд
P>Как наиграетесь, приходите
Не понял. Да, эта функция возвращает true. Тестом будет "f=() -> true; assertTrue(f())".
P>>>Соотвественно, гарантии у вас будут не с т.з. т.Райса, а с т.з. вероятностей
P>>>- функция которая проходит тесты по таблице истинности подходит лучше, чем та, которая эти тесты не проходит
P>·>Мде... Ещё и вероятности пришли.
P>Они всегда были. см выше про т. Райса
P>>>·>Ну добавь. Тесты тут не причём. Сразу замечу, что тестировать наличие постусловий — это уже лютейший бред.
P>>>У вас всё бред, чего вы не понимаете
P>·>Я понимаю на шаг вперёд.
P>Смотрите выше, текст выделен H1, как раз эту вашу способность и "демонстрирует"
Так ещё до того как ты это написал уже говорил, что _необходимость_ ручного тестирования — проблема. Не надо так делать и рассказал как избежать эту необходимость.
P>·>Не понял к чему такой вопрос. Я наоборт утверждаю, что любое мелкое изменение реализации сломает тест, даже если это небольшой рефакторинг или тупо стиль. В этом и проблема такого твоего теста, он хрупкий. Часто падает когда не надо и иногда не падает когда надо, т.к. тестирует внутренние детали реализации, а не ожидания.
P>Хрупкий — это я вам сразу сказал. Так я ж и не предлагаю посимвольное сравнение на все случаи жизни.
deep.eq по-другому тупо не умеет.
P>·>И что ты этим хочешь сказать?
P>Да то, что искать тестами проблемные комбинации вы вспотеете. Нужно искать решение вне тестов.
Ясен пень, тестами комбинации не ищутся, а тестируются. Анализируешь код, coverage report, логи, спеки и т.п., потом пишешь тест подозрительной комбинации и смотришь как себя система ведёт.
P>>>Первые запуски — руками. Потом автоматизируете и получаете интеграционный тест.
P>·>Зачем руками-то? В чём такая необходимость? И почему только первые запуски?
P>Ну можете не руками, а попросить того, кто знает схему бд и язык запросов к ней.
А этот кто-то как будет, ногами что-ли?
Ок, допустим ногами. А какие в базе будут данные на которой этот чаи-гпт будет проверять свои запросы вножную? За 2025 год, правильно?
P>Ну или чат-гпт спросите.
P>Почему первые запуски — потому, что после них как раз будет известен паттерн, по которому нужно будет строить запросы. дальше в ручных проверках смысла не много.
Потом система меняется и паттерн перестаёт функционировать проверенным вручную способом, а тестам — пофиг, они вечнозелёные.
P>>>Вы совсем недавно собирались все комбинации тестировать, разве нет?
P>·>Не все e2e комбинации, а комбинации конкретно данного куска кода, sut.
P>С фильтрами комбинаций столько, что солнце погаснет раньше ваших тестов.
Даже если и так, то до e2e-комбинаций и жизни Вселенной не хватит уж точно.
P>>>·>30 это было число записей, которые могут обеспечить 230 комбинаций. Тебе столько не хватает?
P>>>Фильтры дают на десяток порядков больше комбинаций. В этом и проблем
P>·>Ну сделай 60 записей, будет как раз на десяток порядков больше комбинаций. В чём проблема-то?
P>Проблема в том, что бы генерить данные, нужно знать комбинации которые будут проблемными.
Это же требуется и для того чтобы чтобы руками проверять запросы.