|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||||||||||
Тест простого метода02.06.2025, 21:16. Показов 7911. Ответов 100
Метки нет (Все метки)
Решил попробовать написть тест для одного из методов, где без тестов реально иногда баги вылезают при доработках.
Метод простой - получает на вход подключение к БД, возвращает в виде многоуровневой структуры объектов информацию обо всей структуре БД (таблицы, колонки, индексы, связи, триггеры и т.п.). Общая структура теста в итоге получилась такая:
1. SQL-скрипты, которые делают выборку из 'information_schema' в методе 'Parse'. 2. Логику раскладывания данных из 'information_schema' в экземпляр 'Database'. Однако, если кто-то из разработчиков дополнит обозначенные два пункта новым функционалом, не затронув существующий, тест продолжит корректно продоходить, но при этом фактически не будет покрывать все возможные сценарии метода 'DatabaseParser.Parse'. Получается, что нужен ещё один тест, который будет контролировать, что структура типа 'Database' (и всех используемых в нём типов, состав всех енумов) строго соответствуют ожидаемому состоянию. Т.е. получается:
1. Дополнить метод 'PreapareTestDb' новыми сценариями. 2. Дописать в 'expectedDbStructure.Equals' логику сравнения для новых свойств/типов. P.S.: вопрос - как сделать это правильно ? Потому как сейчас это выглядит слишком громоздко (в плане написания всех вспомогательных методов и подготовки тестовых данных). И не слишком надёжно, т.к. по сути оставляет шанс, что первый тест попросту забудут доработать под новые сценарии, т.к. он просто пройдёт, и его просто не заметят.
0
|
|||||||||||
| 02.06.2025, 21:16 | |
|
Ответы с готовыми решениями:
100
Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода Юнит-тест для метода Unit-тест для void метода |
|
|
|||||
| 04.06.2025, 13:14 | |||||
(хмм... прям на belalugoci похоже)- массовая проверка типов. Например, можно проверить что все Action контроллеров имеют обязательный атрибут. Или что у генерик сервиса существуют все классы, которые определены в его генерик типе. И тому подобные задачи. - когда действительно не хочется открывать методы на internal или public, но тестировать очень хочется. Например когда есть приватные свойства которые создаются самостоятельно или для теста их надо менять. Вот пример библиотеки: Mirrors. Создаём объект, вызываем метод, меняем приватное свойство, снова тестируем. Или если объект создать поноценно невозможно (всё вокруг moq), то некоторые свойства можно только руками прописать.
2
|
|||||
|
|
||
| 04.06.2025, 13:27 | ||
|
Сам вопрос, который здесь обсуждается, как-бы рефлексию не предусматривает (не вижу смысла ее применять). Я считаю, что у kotelok как-то все через-чур переусложнено. Т.е. реально не совсем продумана архитектура: не то самих классов, не то тестов..
1
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||||||||||||
| 04.06.2025, 13:43 [ТС] | ||||||||||||
0
|
||||||||||||
|
|
||
| 04.06.2025, 13:47 | ||
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 04.06.2025, 13:59 [ТС] | ||
|
И если я всю внутреннюю реализацию сервиса разбиваю на кучу адаптеров/провайдеров/хелперов/прочего, то они все оформляются в такие вот классы, которые видны только внутри сборки. И их надо тестировать маленькими специализированными тестами, потому как, отчасти, именно для этого оно всё в такой вид и рефакторилось.
0
|
||
|
|
||
| 04.06.2025, 14:12 | ||
|
Если интернал+атрибут - то по мне это нормально. А если приватное - то перебор. Тогда тестируйте свой единственный открытый метод и разбирайтесь с проблемой результата.
1
|
||
|
|
||
| 04.06.2025, 14:16 | ||
|
Не по теме:
internal class Some, людям сложно понять что вы имеет в виду...
Не совсем понял в какой момент всплыло private, но думаю не стоит заморачиваться ещё и это покрывать тестами. Приватные методы вызываются публичными, и вам в первую очередь нужно следить чтобы public работал как надо. Если кто-то сломает приватный метод, он потянет за собой паблик, и тесты на это отреагируют (по крайне мере должны). Раздробите логику работы вашего мега-класса на отдельные сервисы, покройте их тестами и дальше через время поймёте хватит или ещё что-то добавлять. За один заход на 100% покрыть тестами на всю оставшуюся жизнь навряд получится.
1
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||||||||||||
| 04.06.2025, 14:20 [ТС] | |||||||||||||
|
Вот это вот ...
Добавлено через 3 минуты P.S.: но вообще да, согласен, без явного указания модификатора не сразу понятно - 'internal' он (если верхнего уровня) или 'private' (если является вложенным в другой класс).
0
|
|||||||||||||
|
|
|||
| 04.06.2025, 14:34 | |||
|
Перечитал несколько раз и вроде бы начал смысл парсера понимать. Но возникли другие вопросы - о бессмысленности этого теста.
![]() Тогда вопрос - ЗАЧЕМ сравнивать? Если это банально мигратор изменений схемы БД, то она должна работать в Одну только сторону (собственно как и все миграторы). Никто ничего не сравнивает. Тупо накладывают изменения. Ну где-то ещё от версии зависит, чтобы знать порядок и количество "патчей". Ну сравнили вы - узнали что там есть нестыковки. Дальше что делаете? Стоп или начало миграции по новой схеме? Если стоп - то это ситуация когда каким-то образом кто-то базу обновил. Ну, руки оторвать и дальше нормально работать. А если миграция, то зачем проверять? обновляй схему и всё. Проверить на различия? для чего? Добавлено через 3 минуты Ну и зачем вам база? Ваш метод так и называется - Парсер! Вы его и должны тестировать как парсер. В тесте должен быть готовый объект с наполнением и на входе в парсер - текст JSON который ваш парсер должен распарсить так чтобы при сравнении (глубоком или банально на количество записей) было всё нормально. Вот - это юнит-тест. А то что вы описываете - больше не тест, а модуль пре-инсталляции, которая проверяет и мигрирует БД. Как можно оформить в тест проверку схемы БД, если дальше должны быть тесты, которые тестируют данные из БД? Я к тому что приоритет такого теста должен быть не просто максимальный, а вообще самостоятельно независимый.
1
|
|||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 04.06.2025, 14:44 [ТС] | ||
|
1. Есть JSON, где описано эталонное состояние БД. Ну т.е. какой она должна быть в данной версии сервиса/программы. 2. Есть конкретный экземпляр рабочей/тестовой/девелоперской БД в каком-то не особо предсказуемом состоянии. 3. Задача модуля - выявить расхождения в структуре и построить скрипт приведения п.2 в состояние, описанное в п.1. И выполнить этот скрипт, если не обнаружилось чего-то совсем уж странного.
0
|
||
|
|
||
| 04.06.2025, 14:52 | ||
![]() Ну и из выше сказанного уже вырисовываются модули - парсер который только должен уметь брать текст/JSON и превращать в объект - сравниватель и определитель цели и возможности для обновления Или у вас всегда можно обновиться? даже если нет таблицы, то он её создаст, а если были Дабл типы, то преобразует в Инты? - "ИИ модуль" который при найденных различиях возвращает какой-то результат например сгененрированный запрос на изменения структуры таблицы Это на вскидку, пока вижу на что уже можно разбить. Нет смысла тестировать коннекторы и исполнители запросов. И вот это всё по отдельности и тестируйте.
1
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 04.06.2025, 14:55 [ТС] | ||
|
Реализация такого модуля да, весьма увлекательное мероприятие. Но зато потом оно очень приятно в использовании.
0
|
||
|
|
|||
| 04.06.2025, 15:19 | |||
|
Не по теме:
Но я ожидал более конкретный ответ на предложение о модулях, которые на мой взгляд и должны быть в сервисе и тесте. Добавлено через 3 минуты
0
|
|||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 04.06.2025, 16:02 [ТС] | ||
|
1. Первый - берёт JSON и конвертирует его в объект (ну и отдельные модули для валидации, т.к. это пользовательские данные, и дозаполнения значениями по умолчанию согласно параметрам и логике задачи). 2. Второй - берёт подключение к БД и конвертирует информацию о её структуре в объект, аналогичный п.1. * вот для этого второго пункта в самом первом сообщении была попытка сделать тест. Сравниватель, да. Тоже отдельный модуль. Сравнивает два объекта (результаты п.1 и п.2), определяет расхождения. Он никак не зависит ни от БД, ни от JSON. Другой модуль, на базе найденных расхождений, строит план обновления БД (ну т.е. выстраивает их в том порядке, в котором их в принципе допустимо выполнить, добавляет доп-шаги, если необходимо). Следующий модуль - по плану обновления строит конкретные SQL-скрипты. Далее оно сливается в лог и, если в параметрах вызова указано, применяется к целевой БД.
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|
| 09.06.2025, 16:01 [ТС] | |
|
Всё равно как-то чересчур сложно получается. Даже в рамках одного метода. Слишком больше затраты времени на подготовку входных данных для тестов, на подготовку проверочных данных, на кропотливую ручную сверку этих массивов данных, на оформление их либо в виде JSON, либо в виде многостраничных инициализаторов иерархических коллекций прямо в коде.
Сравнение двух сложных объектов пока реализовал просто через сериализацию обоих в JSON-строку и проверку их точного совпадения. Но не уверен, что это правильный подход, т.к. возможно влияние сериализатора на результат. В итоге на тест всего одного метода много времени потратил, но, учитывая сложность входных/выходных данных, есть ощущение, что не закрыта куча возможных сценариев и, по сути, тест получился не особо полезным. А ещё есть шанс, что во входных/выходных данных могут быть ошибки чисто в силу невнимательности. P.S.: в общем, как-то слишком уж утомительно получается, и пока не понятно, насколько вообще эффективно с точки зрения какой-то реальной пользы.
0
|
|
|
|
|||
| 09.06.2025, 16:11 | |||
|
1
|
|||
|
|
|
| 09.06.2025, 16:26 | |
|
kotelok, если в вашем супер-методе вызываются несколько под-методов, то они все должны быть тестируемые отдельно. Если так не получается или слишком сложно выходит, следовательно имеет место не-доработка общей архитектуры классов.
Вероятно, какое-то кол-во методов будет находится прямо в этом же классе, супер-метод которого тестируете. В этом случае создать объект этого класса и подгрузить нужные проверочные данные для каждого из методов - не составит проблем. Если же часть методов находятся в составе другого класса, то это уже объекты других тестов, отдельных. Тесты поэтому и называются модульными, т.е. должны проверять отдельные модули. Это уже при личном желании можно их все завернуть в один единый тест; однако нужно учитывать, что не каждый сразу разберется что тут происходит и кто кому передает флаг успеха/провала. Добавлено через 2 минуты При коллективной разработке "супер-тесты" не приветствуются вообще. А для личных целей можно сделать все что угодно, хотя, при этом нужно действительно представлять себе весь процесс. Иначе получится тестирую то - сам не знаю что.
1
|
|
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
|
| 09.06.2025, 20:39 | |
|
kotelok, разбить тесты не означает полностью сменить систему тестирования.
Был в этих двух смежных темах коммент с видосами, я просмотрел только вводный. Так вот, тестов на одну и ту же сущность может быть много. А не один спагетти-кот. А тестирование "черных ящиков", ещё тот прикол. Это внутренние тесты самого разработчика, и они ведутся самим автором. И задолго до релиза и сборки. Или я попал во вселенную где архитектура софта и железа - другая? p.s. И как уже много раз, явно или косвенно, разжевали, что тесты - это на долгосрочную разработку. А не: Лично я не представляю толковую программу, которую не тестируют, вот в одиночку даже пишешь и каждую функцию/класс тестируешь, что бы потом не уходить в дебаг часами и днями. p.p.s Какой то планировщик с отчетами для радио прошлого века, наформошлепил... очень авторитетное мнение.
1
|
|
| 09.06.2025, 20:39 | |
|
Unit тест для метода Юнит-тест для асинхронного метода Unit тест для метода Вызов переменной метода A из метода В Вызов метода, ожидающего завершение другого метода Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров
В текущей версии модели успешно реализован ключевой механизм. . .
|
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям
Реализованные компоненты:
Механизм закисления почвы через протонную помпу
Конкуренция между типами микориз
pH как триггер сукцессии
C/ P соотношение. . .
|
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
|
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
|
|
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы
## О чём эта статья
В процессе построения ОДУ-модели (система дифференциальных. . .
|
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет)
Содержание проекта
Симуляция вековой (50 лет) экологической сукцессии в почве леса
Основные участники: АМ-гриб, ЭКМ-гриб,. . .
|
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов
Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
|
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация
В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
|