Re[95]: Что такое Dependency Rejection
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.03.24 19:38
Оценка:
Здравствуйте, ·, Вы писали:

P>>·>smoke tests — как вишенка на торт, но в остальном — проверять две вещи: части работают, части собираются между собой нужным образом.

P>>Что это за тесты, кто их выполняет?
·>CI/CD

Чем ваши acceptance и smoke отличаются от e2e ?

P>>Минорная — это значит, что есть вещи более важные

P>>Если у вас нет хотя бы одного 1..4 никакие тесты вам не помогут, хоть обмажтесь.
·>А без тестов 1-6 уйдут лесом. Единственное, что может не сразу, но уйдут точно.

Тесты напрямую не влияют на качество — это просто индикаторы симптомов.
Более того, если тесты зеленые, это говорит всего лишь "не обнаружили", а что там на самом деле с софтиной — а хрен его знает, если у вас нет 1-4
Хотите повышать качество — нужно проектировать, кодить больше, лучше, помогать другим, документировать, итд, итд.

P>>Похоже, ваш капасити переполнен три месяца назад. Вы здесь, извините, порете отсебятину.

·>У тебя память как у рыбки. Цитирую:
·>

·>·>потенциально может быть null — ты не дождёшься окончания.


Я шота не понял ваш аргумент.

P>>Какие именно поля на null ? ui, dto, bl, конфиг, бд?

·>Перечитай топик, всё написано. Твоя цитата:
·>

·>...в составе юнит-тестов, где нас интересуют подробности
·>— а что если в колонке пусто


Непонятный аргумент. Подробнее никак?

P>>Смотрите внимательно — щас будут примеры и вы наверняка скажете, что у вас такого быть не может, невозможно, никогда, у вас багов вообще не бывает итд.

·>Таких примитивных тривиальных багов как у вас — не бывает. Ибо это всё лечится элементарно.

Видите — я угадал.

·>Подавляющее большинство багов — неверно поняли спеку и реализовали поведение не такое, какое хотел юзер. Но такие баги в большинстве ловятся на этапе демо.


Это значит, что у вас простой кейс — для всего дадена спека. Что делать будете, кода результат вашей работы это и спека, и софт по ней?

·>Так фоновой процессинг н е с божьего попущения работает, а с того же мочёного источника времени.


Вы зачем то снова пустились в фантазирование. Юзер у вас что, на бакенде сидит? Нет ведь. Он в каком то клиентском приложении. Вот там и ищите фоновый процессинг.
Я вам просто пример привел, откуда может прийти проблема, которая в ваших моках никак не отражена.

P>>Пофиксили, и выяснили, юзер всё равно не логаутится, т.е. время жизни сессии берется из конфига, который неправильно смержился.

·>Не понял. По ошибке указали в прод конфиге не 30 минут, а 300?

В проде указали 30 минут, а из за мержа конфигов у вас стало 300, например, потому что это дефолтное значение. Это снова пример проблемы которая идет мимо ваших моков.

·>На это дело есть специальный процесс, который показывает diff конфига между продом и тестом. Каждая разница должна быть проревьювена и заапрувлена.

Вот вам дифф ничего и не показал — всё кошерно. А на проде дефолтное значение перетерло значение из конфига. Упс.

P>>Пофиксили, и выяснили, что всё равно не логаутится — ваш фикс фонового процессинга сломал один из долгоиграющих кейсов, разработчик Вася подкинул рядом с вашим кодом свой, и фоновый процессинг всё равно обновляет сессию.

·>Детский сад. Не используйте глобальные переменные.

Забавная телепатия. Где вы увидели глобальные переменные?

P>>Пофиксили и это, и выяснили, что логаут стартует когда подходит ttl сессии, но ничего не делает — потому что очередь шедулинга с этим связаный забита под завязку другими вещами.

·>Забитость очереди — это красный сигнал в мониторинге.

Именно что в мониторинге, а не в ваших тестах на моках. И только под нагрузкой.

P>>Пофиксили и это — обнаружили, что строчка тестового кода пролезла на прод в одном из больших пул реквестов и логаут вызывается только для тестовых юзеров.

·>"строчка тестового кода" это как?! Тестовый код физически лежит в другом каталоге от прода.

Очень просто. Код для тестов и тесты для кода это две большие разницы, как говорят в Одессе.
Например, разработчик кое что подтюнил в коде, что бы легче было воспроизвести другую багу. И забыл это убрать.

P>>Проблему нужно решать не моками, а дизайном.

·>Ага, т.е. опять оффтоп. Мы же тут обсуждаем тесты, а не дизайн.

Вы до сих пор название топика не вкурили? dependency rejection это целиком про дизайн.
А тесты это всего лишь результат того, как вы дизайн построили.
Построили дизайн под моки — естественно, кроме моков ничего и не будет.

P>>Например — отделить фоновый процессинг от интерактивного, что бы у него даже не было никакой возможности получить токен для обновления.

·>Мде. Тупо — не используйте глобальные переменные.

Это всё мимо. Экземпляр UI приложения это штука глобальная, вне зависимости от того, где вы держите переменную app — глобально или в стеке функции main или хоть вообще нигде. Это ж не сервер, где на запрос можно поднимать хоть целый процесс.
Вопрос в том, как у вас сделано разделение фонового и интерактивного приложений.

P>>А если время сессии это критическая вещь, то e2e ну просится — архитектура аутентификации всегда сложная, там много чего может пойти странными путями.

·>Это легко лечится: Любая вещь, сложная или не сложная — первый вопрос на который должен быть дан ответ прежде чем приступать к обсуждению дизайна и уж тем более реализации — как мы это можем покрыть быстрыми автотестами?

Вот-вот — фоновый процессинг совместили с интерактивным именно потому, что так быстрее было тестировать.
Отсюда и баги из за этого совмещения — вечноактивный юзер.

P>>В данном случае здесь решение что через мониторинг, что через e2e будет приблизительно одинаковым.

·>Мониторинг обнаруживает проблемы мгновенно, в отличие от.

Да, вы эту сказку много раз повторяли — у вас мониторинг любую даже гипотетически возможную проблему обнаруживает сразу.

·>e2e чего? e2e — это сценарий, когда какой-то тестовый юзер чего-то сделал и проверяем, что система совершила ожидаемые действия. А statement создаётся для реальных юзеров для действий которые они совершили.


Вы что, повсюду в бизнес-логике пишете "if user.isTest() " ? Очень вряд ли. Интеграция для тестового юзера и реального будет та же самая. Соответственно, обнаруженные проблемы практически наверняка будут играть и для тестовых юзеров.

·>Тут речь идёт о том, что _все_ тесты должны быть запущены и успешно пройдены до того, как код увидят юзеры. А у вас это настолько "задешево", что вы не можете себе этого позволить и выполняеете acceptance частично.


Мы уже выясняли — вы держите только ту часть acceptance, которую можно выполнить за полчаса. А другие на идут дальше этого 1%

P>>Ну да, вы выдумали какое то своё определение интеграционного кода.

·>Да мне похрен на определения. Я написал суть. Но на суть тебе плевать, придираешься к терминологии.

Через ваши доморощенные определения крайне трудно продираться.

P>>·>Если вы не в сосотянии протестировать контроллер, роутер, юзекйс валидацию и сериализацию без e2e — у вас проблемы.

P>>Успокойтесь, e2e это не для теста контролера. Наверное вы забыли, что я вам предлагал тестировать валидацию юнит-тестами?
·>А чем тестируется контроллер-то?

Интеграционными — средний уровень в пирамиде. Я ж вам объяснял уже.

P>>Итого — 1000 пускаете как раньше, + 10 новых регулярно.

·>Зачем, чтобы что? Гораздо выгоднее вместо этой хрени пойти в паб отметить — эффект гораздо лучше.

Что вам непонятно было в прошлый раз? Вы продолжаете задавать один и тот же вопрос, получаете один и тот же ответ. Чего вы ждете?

P>>Похоже, X + 1 у вас может быть меньше X. Забавно!

·>Потому что твоё "добавление" имеет отрицательный эффект. Тратит ресурсы с нулевой пользой. Зачем это +1 запускать после релиза, если мы можем себе это позволить запустить до?

Вы же сами сказали — у вас ажно 1% покрыт. Вот на остальные 99% и нужно придумать чтото получше чем есть у вас.

P>>Откуда возьмется регрессия?

·>Если эти ваши "новые" тесты могут упасть в принципе, то значит у вас регрессия не найденная тестами до деплоя.

Теорема Райса с вами не согласна. Нету у вас 100% надежного способа гарантировать даже true из boolean.

Баги имеют свойство воспроизводиться повторно, например, потому что
1 часто у бага больше одной причины — далеко не все они дружно сами себя документируют в тестовом прогоне
2 разница прода и стейджа (нагрузка, время, объемы данных, итд)
3 итд

P>>Вот и отлично — значит наличие красных тестов наутро сообщит вам о проблеме еще на стейдже.

·>Зачем наутро? Через 20 минут же, спасибо мокам.

Вашу интеграцию тестируют acceptance и smoke. я вот не удивлюсь, если окажется что ваши acсeptance это ровно то же, что и e2e

P>>"Те, для которых написаны тесты — ясен пень не доходят(до прода)" — в скобках это контекст обозначил

·>И? В логику не умеешь? Помогу: это значит, что могут доходить только те баги, для которых не существует тестов. Из чего ты высосал "багов быть не может" — это мне даже неинтересно.

А также те, для которых тесты существуют, но причин более одной, разница прода и стейджа итд.

·>Ты в логику не умеешь совершенно. Это значит, что этот тест будет зелёным и на проде тоже.


Теорема Райса с вами не согласна. Нету у вас 100% надежного способа гарантировать даже true из boolean.

> Либо он может быть красным синхронно с какой-нибудь лампочкой в системе мониторинга. Что делает запуск теста — бесполезным, никакой новой информации он дать не может.


А еще он поможет подсветиться лампочке в мониторинга до того, как юзер напорется на проблему, а не после
Вы разницу до и после надеюсь понимаете?

P>>>>Вы из своих функций вызываете другие свои функции? Вот вам и интеграционный код. Посмотрите, сколько у вас такого.

P>>·>Непокрытого лёгкими тестами? Полторы строчки, всё верно.
P>>Сюда нужно вписать data complexity. Хороший пример — те самые фильтры.
·>Какое это имеет отношение к интеграционному коду?

Вы же их тестировать предложили в связке с бд. Так? Это и есть интеграционный код.
Комбинаций у вас нет. Так?
Вот вам и ответ.

P>>Относительно других методов. Ваши косвенные тесты упираются в теорему Райса.

·>Ага-ага, а ваши "прямые" тесты не упираются. Да вы круты неимоверно.

Вы одной ногой понимаете, а другой — уже нет.
Мой подход того же поля что и статическая типизация — проверяет структуру, синтаксис.

Структурная эквивалентность, синтаксис теореме Райса не подчиняются.
А вот ваши тесты это чистой воды семантические свойства которые полностью подчиняются теореме Райса

P>>Проектирование — формальные методы, например, доказательства тех или иных свойств.

·>Оффтоп, т.к. мы обсуждаем методы тестирования.

Это вы так хотите. Я все время говорю про подход к дизайну. Dependency Rejection — это принцип дизайна прежде всего

P>>Как это будет с linq вам Синклер рядом показал. Сама задача в том, что фильтровать нужно по выражению от юзера, который а хрен знает что может понавыбирать.

·>Я указал на недостатки и дыры в таком подходе в ответе ему.

Ваши тесты еще хуже. По уму, нужно и то и другое. Но вы почему то выбираете худшее из двух.
Ваши тесты ничего не дают без знания конкретных комбинаций на которых можно отработать тест

P>>В том то и дело. А что у вас есть кроме тестов?

·>Всё что надо, не волнуйся, но это оффтоп. Если интересно, заводи новую тему.

Я вам уже третий месяц предлагаю показать это "всё что надо" и вы приводите только тесты, которые требуют комбинаций которых у вас нет

·>Может быть, но тебе не удалось. Ни для примере Буравчика, ни в примере Фаулера.


У Буравчика как раз тот случай, где нужны моки. Я же сразу это сказал, а вы третий месяц срываете покровы.

·>Похрен на дизайн. Ты простую мысль так и не понял. Проверять кол-во записей и проверять наличие top — даёт те же гарантии. Но проверка кол-ва записей проверяет больше.


В том то и дело, что не даёт. У вас нет комбинаций, а потому проверяние количества записей смысла не имеет — в тестовой базе просто нет тех самых данных.

P>>Полчаса это десятки минут. e2e это вобщем тот же acceptance. Если у вас есть такое, чего же вы здесь выступаете?

·>Выступаю о том, что это всё выполняется ещё до деплоя. Не нужно выполнять ничего после деплоя (ок, один smoke test), и уж тем более частично по random.

Вы еще и кластер по acceptance разворачиваете. Или у вас там тоже моки?

P>>В том то и дело — я проверяю структуру, а вы пытаетесь тестами семантику проверять. Отсюда ясно, что вашими тестами вы в теорему Райса упретесь гораздо раньше

·>Ты не проверяешь структуру, ты копипастишь её из прод-кода в тест-код. Т.е. для надёжности для надёжности пишешь пишешь дважды ровно то же самое то же самое. А то вдруг чего. А то вдруг чего.

В прод коде только билдер. Откуда копипаста взялась?

·>Похрен. Идёт речь про тесты. Ты заявляешь "Вы так и не показали ни одного автоматического теста". И что, и не обязан был. Ты не показал вообще никакого теста. И не сможешь, ясен пень.


В данном случае я вам все показал, кроме реального запроса, который будет построен билдером. Там естественно, будет не limit, и не набор AND OR итд.

P>>Ручные методы это в т.ч. exploratory, и вообще исследование.

·>И? Из ручного тут лишь само создание автоматических тестов. Да, если ты не знал — код тестов пишут вручную. Если вы их герените автоматом, то не делайте так больше.

Автоматизируется только рутина. Результат exploratory это не автоматический тест, а обозначение проблемы и перечня новых тест кейсов. Будут ли они автоматизироваться, или нет, дело десятое

P>>·>Главное пока умалчиваешь: тест как выглядит для этого кода? Ну где там deep.eq, pattern или что?

P>>Вам примера Синклера недостаточно, вы хотите у меня тож самое спросить?
P>>
P>>const request = create(
P>>    User, 
P>>    u => u.many(q => q.filter(f => f(filterExpression))
P>>                      .orderBy(o => u('created'))
P>>                  .top(10)
P>>    )
P>>);
P>>expect(builder({ параметры })).to.deep.eq(request)
P>>

P>>вот так мы можем проверить, добавляет ли билдер top или нет. Билдер будет примерно как у Синклера.
·>Не понял. Где тут прод-код, где тут тест-код? Напиши однозначно — код под тестом и сам тест.

Это весь тест. прод код — функция builder. Параметры я опустил, для наглядности, как и filterExpression
Это всё из другого проекта, я им больше не занимаюсь

P>>Забавно, вы вырезали часть цитаты, и не знаете, что было в той части, что вы же и выбросили? Ищите — я для вас синим подсветил

·>Нашел. Там нет ответа на мой вопрос.

Попробуйте заново сформулировать вопрос. А на ваши огрызки цитат ответы ищите в синих буквах.

P>>·>"у запроса всегда есть лимит" в переводе в твоём случае будет "функция isOdd всегда использует битовую операцию взятия младшего бита".

P>>Вы уже почти научились. В случае с битами все просто — половина целых четные, половина — нечетные. Это значит, что тестовый набор вы сможете намастырить самостоятельно.
·>Половина бесконечности, если что — тоже бесконечность.

Вот вы важное ограничение вашего подхода и нашли — бесконечность.
А вот у пост-условия такого ограничения нет в принципе.
Идея понятна?

P>>А вот где взять запрос, у которого будет нарушено свойство длины — загадка

·>Что за свойство длины?

Известно какое — в память не влазит
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.