Deutsch

Автоматизация тестирования

7590  1 2 3 4 5 6 7 8 9 10 все
alex445 коренной житель09.11.23 14:29
NEW 09.11.23 14:29 
в ответ Программист 09.11.23 13:21, Последний раз изменено 09.11.23 14:50 (alex445)
У нас сейчас есть актуальный кейс - проблема с БД. Создаем тикет у оракла и они (оракл) требуют Verbose лог с проблемой. Генерим лог, отправляем в оракл на анализ.
Собственно говоря, не просто так придуманы 1) уровни логгирования (error, warning, info, debug и еще куча кастомных уровней) и 2) не просто так придуманы циклические логи, сроки давности логов и ограничения по размеру логов.
Все это работает на то, чтобы получать нужную для исследования проблемы информацию. И да, если кто-то вместо уровня debug использует info, то он сам себе злобный буратино :)

Это я всё понимаю. Не понимаю, стоит ли действительно писать так:

лог

валидатор входящих

лог

перформанс каунтер

лог

строчка кода

лог

валидатор предыдущей строчки кода

лог

ветвистая обработка исключений - по логу на каждую обработку


На одну строчку кода 20 строчек обслуги, не считая скобок. Функция занимает экран-полтора, хотя делают по сути одну операцию. И так в почти каждой функции. А функций может быть 10-20 друг друга вызывать. И когда знакомишься с таким кодом, долго думаешь, что тут происходит. И так трудно докопаться до сути, продравшись через дебри паттернов, так ещё у себя в голове и очистить всё от обслуживающей логики нужно.


Может, проще дамп памяти скинуть? Там как раз весь контекст. А читать все эти verbose - кто их будет?

MrSanders коренной житель09.11.23 14:30
NEW 09.11.23 14:30 
в ответ Murr 09.11.23 13:55

Тоже мне бином Ньютона. Смортря чей компилятор. Микрософтовский, значит микрософт.

Пришёл менеджер, наорал на поддержку "почему на каждый инцидент в среднем 25 часов тратится", ему сказали что повторить ошибку без данных сложно. Он побежал к разработчикам и потребовал возможность записывать каждый чих. Вот тебе и записи в лог где можно и где нельзя.

Программист коренной житель09.11.23 14:42
NEW 09.11.23 14:42 
в ответ alex445 09.11.23 14:29
Может, проще дамп памяти скинуть?

Дамп памяти надо еще уметь анализировать. И нет, его скинуть не проще. Т.к. дамп - штука крупная и на каждую ошибку генерировать по дампу - очень накладно.


А читать все эти verbose - кто их будет?

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

alex445 коренной житель09.11.23 14:55
NEW 09.11.23 14:55 
в ответ Программист 09.11.23 14:42, Последний раз изменено 09.11.23 14:59 (alex445)
Дамп памяти надо еще уметь анализировать.

Я думал, это такая штука, которую в какой-нибудь Студии открыл, а она тебе рраз - и открылся код, где возникает ошибка, с остановом на нужной строчке, и все данные в контексте всего стека вызовов, и по стеку гулять можно. Что, нету такого? А было бы удобно... Для суперсложных распределённых систем этого может быть недостаточно, но для основного большинства ошибок - вполне.


Логирование, это прямо какая-то чуждая кодированию вещь, требующая дофига обслуги, настроек и засоряющая код. Это как меню в ресторане вместо выбора самих блюд. Если бы были блюда готовые и можно выбрать из реальных, а не нарисованных, то это лучший вариант, чем листать всякие книжки с картинками. Так и в багфиксинге - если можно саму память и состояние приложения задампить со всем стеком вызовов, получая ситуацию ошибки точно такую же, как возникла у клиента, то все эти логи нафиг не нужны. В них самих ошибок можно наделать дофига.

Murr патриот09.11.23 19:35
Murr
NEW 09.11.23 19:35 
в ответ MrSanders 09.11.23 14:30

Вот тебе и записи в лог где можно и где нельзя.

------

Ндаа... и это вместо того, чтобы корректно проимплементить компоненты компилятора...


Но лучший вариант все же был у меня.

У нас тогда пошли массовые проблемы с подключением к Ораклу... что-то работало, что-то отваливалось...

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

А потом был переход на постгрее и смена команды разработки... оставившей всю обработку оракловских ехсептионов...

daduda свой человек09.11.23 19:58
09.11.23 19:58 
в ответ alex445 08.11.23 22:59
Вопрос. А есть ли смысл в таких логах? Кто потом эти терабайты читает и разбирает?

Мальчик, или в школу. Там тебя научат делать ELK стек и анализировать логи с помощью ChatGPT


Зы. Ты случайно не писал систему логирования для ActiveMQ ? А то там ничего не логируется.

daduda свой человек09.11.23 20:04
NEW 09.11.23 20:04 
в ответ alex445 09.11.23 14:55
Логирование, это прямо какая-то чуждая кодированию вещь, требующая дофига обслуги, настроек и засоряющая код

Мальчик, тебе нужно в ясельную группу. На горшок.


Зы. Ты в курсе, что такое разделение ответственности в коже (code separation) ?


Выделяй inner helper class вызывай из него логируемый метод и добавляй столько логирования, сколько нужно.


А то развели тут клуб благородных девиц.

AlexNek патриот09.11.23 21:41
AlexNek
NEW 09.11.23 21:41 
в ответ alex445 09.11.23 14:29
Может, проще дамп памяти скинуть?

Как можно можно лучше понять событие - увидев фотку или глянуть видео?

Особенно когда важно знать что за чем идёт.

alex445 коренной житель09.11.23 22:12
NEW 09.11.23 22:12 
в ответ AlexNek 09.11.23 21:41, Последний раз изменено 09.11.23 22:20 (alex445)

Лучше дамп памяти со стеком вызовов и всем контекстом, и остановом в точке возникновения ошибки, чем какие-то тонны текстовых писулек.


Можно разделить как в логировании: уровень warning - небольшой дампчик ближнего окружения; уровень error - дамп побольше, окружение поширше; уровень fatal super-puper apocalypse - полный дамп приложения в RAM. Короче, настроить можно и по мере накопления статистики решить, насколько много дампить. Вобщем, всё как в текстовых логах, только без текстовых логов.


Я вообще поражаюсь, как люди любят занимать себя пустой работой, типа написания логов или тестов в объёме, на порядок превышающем сам код. Вместо того, чтобы придумать, как бы от работы освободиться и заняться любимым делом или предаваться ничегонеделанию. Лень - двигатель прогресса! А от работы и кони дохнут.

AlexNek патриот09.11.23 22:24
AlexNek
NEW 09.11.23 22:24 
в ответ alex445 09.11.23 22:12
и остановом в точке возникновения ошибки

А кто интересно будет знать эту точку? шок

Я уже не говорю о том, что дапм памяти подразумевает немного другое.


или предаваться ничегонеделанию

вот именно от этого "нормальные" кони и дохнут бебе

alex445 коренной житель09.11.23 23:58
NEW 09.11.23 23:58 
в ответ AlexNek 09.11.23 22:24

Не усложняйте.

Программист коренной житель10.11.23 09:56
NEW 10.11.23 09:56 
в ответ alex445 09.11.23 14:55
Я думал, это такая штука, которую в какой-нибудь Студии открыл, а она тебе рраз - и открылся код, где возникает ошибка, с остановом на нужной строчке, и все данные в контексте всего стека вызовов, и по стеку гулять можно. Что, нету такого? А было бы удобно...

Не то, чтобы такого нет :) Но, 1) создать минидамп - это дорого (это сотни мегабайт) 2) в студии дамп открыть можно, но для анализа дампа студии мало, нужны какие-то хардкорные приложения типа WinDbg 3) дамп без pdb файлов - мусор (ну если только ты не гуру ассемблера :), да и то не факт), а значит надо делать добавлять менеджмент pdb файлов.

Так что ниша дампов очень узкая. Это либо дэдлоки (тогда пользователь сам должен создать дамп) , либо это перехват исключения перед тем, как схлопнется приложение.

alex445 коренной житель11.11.23 13:47
NEW 11.11.23 13:47 
в ответ Программист 10.11.23 09:56

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


Иногда бывает, что нет времени всё делать по фен-шую, писать тесты, интерфейсы и прочее - работать надо. А марафет потом как-нибудь наведём. И вот настаёт этот волнительный момент, когда можно расслабиться и пару дней пинать балду на расслабоне дописывать интерфейсы к классам, и тут разработчики IDE тебе подсирают - есть оказывается команда для извлечения интерфейса в пару кнопок. Предатели!

Программист коренной житель11.11.23 18:57
NEW 11.11.23 18:57 
в ответ alex445 11.11.23 13:47
А не проще наоборот - сначала класс, а интерфейс из него одной командой вытаскивается?

Новечку, конечно, проще.

Однако в тот момент, когда ты начнешь писать тестируемый код, ты поймешь, что сначала должны быть интерфейсы :) Плюс ко всему, подход "интерфейсы вперед" позволяет задумываться об архитектуре на ренней фазе.


А марафет потом как-нибудь наведём.

Не наведешь :)

Во-первых, в 95% случаев на рефакторинг нет ни времени, ни бюджета. Т.е. должны быть очень веские причины (функционал, баги) для рефакторинга.

Во-вторых, код типа такого (все на классах)

public void Foo (DbConnection db, UserProvider provider)
{
    UserService srv = new UserService (db);
    
    User user = srv.GetUser (provider);
    if (user != null)
    {
        user.Login ();
    }
}

нетестируем и без рефакторинга тут уже ничего не сделаешь.



alex445 коренной житель11.11.23 19:57
NEW 11.11.23 19:57 
в ответ Программист 11.11.23 18:57, Последний раз изменено 11.11.23 20:06 (alex445)

Всё легко и просто тестируется. Берёшь вместо реальной БД тестовую, которая может даже быть частичной копией реальной, и тестируешь прямо сам класс, а не кучку моков. Заодно и проблемы с тестовыми данными отпадают, которые что с вашими интерфейсами, что без, всё равно нужно откуда-то взять, как-то нагенерить.


Ещё такое мнение читал, что интерфейсы мол для быстрой замены реализаций. Как у вас в 95% случаев нет времени на рефакторинг, так и в 95% случаев никто реализацию потом не меняет. Вот в моём проекте 15-летней давности всё на интерфейсах, а UI как был из старинных времён, так его никто и не заменил. Как и вообще почти всё внутри. И сейчас логику просто переписываем с нуля, стараясь по возможности повторить её на новых версиях фреймворка, языка и вообще всего. А старые интерфейсы просто захламляли код.


Если надо что-то заменить, то обычно сначала отказываются от замены, потом опять отказываются, потом ещё раз отказываются, потом это всё работает уже лет 5-10, а потом просто переписывают. И снова 5-10 лет без замены. Спонтанные подмены СУБД, GUI и прочих вещей - это из феншуйских задвигов. В реальном кровавом энтерпрайзе всем этим на заморачиваются, а просто не трогают, пока оно работает и пока не припрёт. В моём проекте до сих пор бы не трогали, и жило бы всё и 20 лет, и дольше, но IE уже не поддерживается.

Программист коренной житель11.11.23 20:19
NEW 11.11.23 20:19 
в ответ alex445 11.11.23 19:57

Ну во-первых, подсовывать под каждый тест реальную БД - это очень накладно. При этом не забываем, что тесты должны быть атомарными, т.е. независимыми друг от друга. Более или менее эффективно это может работать только с помощью собственного расширения для тестового фреймворка + работающая со снэпшотами БД (оракл или MS) + самописный UnitOfWork, который надо использовать как в расширении тестового фреймворка, так и в продуктивном коде. И даже в этом случае, производительность таких тестов будет желать лучшего. Я уж не говорю о том, что будут не юнит-тесты :D


Во-вторых, приведенный код нестестируем не столько из-за БД, сколько из-за new и из-за того, что UserService - реальный объект, а значит нельза мокнуть функцию GetUser. Которая, в свою очередь, тоже возвращает реальный объект, а значит нельзя проверить была ли вызвана функция Login :)


Короче говоря, использование классов сделали эту функцию нетестируемой юнит-тестами :) Это не значит, что функцию нельзя протестировать, но труда для создания теста надо будет вложить в десятки раз больше. Так что лучше было бы сразу писать на абстракциях :D

AlexNek патриот11.11.23 21:03
AlexNek
NEW 11.11.23 21:03 
в ответ alex445 11.11.23 13:47
А не проще наоборот - сначала класс, а интерфейс из него одной командой вытаскивается?

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


что нет времени всё делать по фен-шую, писать тесты, интерфейсы и прочее - работать надо.

Так именно правильная работа в этом и заключается - всё делать по фен-шую, писать тесты, интерфейсы и прочее.


Всё, что делается по другому, со временем превращается в большую кучу мусора, как есть актуальный проект.

При этом, даже если делать все по правилам нет гарантии получения отличного кода.


Но переубеждать кого то в этом - бессмыслнная затея.

Murr патриот11.11.23 23:14
Murr
NEW 11.11.23 23:14 
в ответ alex445 11.11.23 19:57

подмены СУБД, GUI и прочих вещей

-----

Если написано нормально, то любая из замен делается в пределах уровня без особых проблем.

Murr патриот11.11.23 23:20
Murr
NEW 11.11.23 23:20 
в ответ Программист 11.11.23 20:19

значит нельза

-----

Мона. Надо сунуть имплементацию в дллку и подставить в тестах моку и все будет... :)


Так что лучше было бы сразу писать на абстракциях

------

Гы... а сразу - оно спагетти после 10-20 лет модификации фриками...

Murr патриот11.11.23 23:24
Murr
NEW 11.11.23 23:24 
в ответ AlexNek 11.11.23 21:03

со временем превращается в большую кучу мусора

------

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

Главное в проекте - успеть спрыгнуть до того как выяснится что большая куча мусора уже образовалась.

1 2 3 4 5 6 7 8 9 10 все