|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||||||||||
Тест простого метода02.06.2025, 21:16. Показов 8303. Ответов 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 из метода В Вызов метода, ожидающего завершение другого метода Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет!
За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js.
В помощники взял Яндекс-Алису.
Было создано три зала на разные интересы.
исторические и ретро
сериал Хичкок. . .
|
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|