|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||||||||||
Тест простого метода02.06.2025, 21:16. Показов 7914. Ответов 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 метода |
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 09.06.2025, 21:35 [ТС] | ||
|
0
|
||
|
|
||
| 09.06.2025, 22:02 | ||
|
Мы создали код, который переделывает СУБД к некоторому шаблону, запустили и... В самой БД что-то пошло не так, тест провален. Кто виноват: код или сама БД (движок)? Не ясно.. А на самом деле, тест должен проверять валидность полученных данных, пришедших в него извне (из СУБД). При этом сама СУБД не нужна как таковая: различные правильные/неправильные объекты можно нагенерировать и без БД. Тест должен отвечать за метод, который можно тут же исправить. А не за внешние поставщики данных, у которых своя собственная судьба.. Есть проекты, которые в будущем могут получать некоторые данные из других источников. Этих источников еще в помине нет, но код пишется.. И как его тестировать? Ждать последнего дня, когда кто-то скажет "БД завели - пробуйте!". Так это не работает.
2
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||||||||||||
| 09.06.2025, 22:46 [ТС] | ||||||||||||
|
Пример вообще без конкретной специфики (а то всё куда-то в сторону уходит обсуждение). Есть какой-то источник данных, спрятанный за абстракций и возвращающий какие-то сырые (но слегка структурированные данные). Конкретная реализация может быть - поверх СУБД, поверх JSON (это где-то отдельно тестируется, каждая конкретная реализация, тут не суть).
Сейчас мокается 'IDataProvider' на все возможные комбинации входных данных. Для каждой такой комбинации составляется единственный верный вариант выходных данных. Из теста вызывается метод 'Parse'. Результат (через сериализацию в JSON) сравнивается с ожидаемым. И получается достаточно большой массив входных/выходных данных, которые надо не только вбить вручную, но ещё и вбить очень внимательно, чтобы ни в одном из десятков вариантов не допустить ни единой ошибки. Внутренние приватные методы (Filter/Sort/Proc) никак отдельно не тестируются (потому что они приватные, потому что это детали реализации). Если их раскрыть наружу и тоже протестировать, то для каждого из них тоже будет набор входных/выходных данных для тестирования. Но при этом общий тест метода 'Parse' тоже будет необходим, чтобы проверить что именно его логика не сломана (ну т.е., банально, что кто-то там не забыл раскомментировать вызов 'Filter', закомментированный для какого-то эксперимента).
0
|
||||||||||||
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
|||
| 09.06.2025, 22:52 | |||
|
Но вот простой пример как я тестил(абы как) код, который вообщем то и не востребован(ТС забил). Но тем не менее тесты я провел для себя и своего кода. 1. Кликабельная координатная сетка (делал просто для себя) 2. Преобразование G (для себя, что бы на каждом шагу шифрования быть уверенным в его работоспособности + для ТС, что бы показать как справляться со сложными задачами, а именно разбивать не более мелкие и проверять их работу) А так как я писал его спустя рукава, а не под ответственность, то ошибки были наверняка(и в первом и во втором варианте, учитывая и кривую документацию алгоритма шифрования и математическую составляющую с которой я не был знаком). В сложном коде, объемном, ошибки будут в любом случае, как ты не тужься. И часть их закрывают тесты. Ну не в боевом же режиме их отлавливать, потери информации или устройств, или ещё хуже, жизней. Лучше потратить на хороших специалистов и их количество, которые сделают тесты и закроют большую их часть. Я хз что ещё добавить. "Есть время раскидывать камни, есть время собирать камни" Добавлено через 1 минуту В подавляющем случае - это займет столетия или вечность.
1
|
|||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 09.06.2025, 23:00 [ТС] | ||
|
1. Сначала написал тестируемый метод (Parse). 2. Потом реализовал генератор входных данных по определённым критериям, чтобы покрыть большинство сценариев. 3. Далее прогнал эти входные данные через п.1 и получил результат для каждого набора данных из п.2. 4. Сохранил полученные пары входных/выходных данных в виде JSON в ресурсы тестовой сборки. 5. Использую ресурсы из п.4. для проведения тестов. Сэкономил вечность. Но ощущение, что что-то тут не так.
0
|
||
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
|||
| 09.06.2025, 23:06 | |||
|
Закрытые методы тестирует автор класса. Открытые - все кто угодно, я не знаю ролей комманды, а комманда в одно лицо, и он такой, да Петя, ты тестируешь паблик, да Козлов, понял вас, будет сделано. Михалыч, допиши там пару методов, и открой для тестирования. =) Добавлено через 2 минуты 1. Что то тут не так, и латаем течь судна тряпками. 2. Я уже так замотался, что уже всё не так. Отложите эту тему на пару недель. Возможно что то прояснится или хотя бы появится большая конкретика. Стучатся головой об стену не самый лучший вариант, даже если бОшка крепкая.
1
|
|||
|
|
|||||
| 09.06.2025, 23:06 | |||||
|
- заведомо правильные - заведомо неправильные - null-евые - искаженные - ... и проверяете свой метод.
1
|
|||||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 09.06.2025, 23:14 [ТС] | ||
|
Добавлено через 3 минуты
0
|
||
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
||
| 09.06.2025, 23:18 | ||
|
И если где то есть ещё непонятки, то опишите их по пунктами. Так их легче разбирать. А не всю гору обнять. Например: Как тестировать закрытые методы. Что делать если тестируемый метод/класс берет на себя много ролей/функций. и т.д. Если не описывать вопросы четко, не разбивать сложные вопросы на более мелкие, кругами ходить можно вечно.
0
|
||
|
|
||
| 09.06.2025, 23:38 | ||
|
Так не пойдет, если говорить о тестировании предметно. В принципе, уже много всеми проговорено об этом, но подведу некоторые итоги: - тестируются (модульно) функционально законченные объемы кода (методы). - тестированию должны подлежать каждые кусочки функционально-зависимого кода. - тестирование не панацея от всех бед, но и не предмет для разгула фантазии: нужно четко понимать цель тестов и их необходимость в принципе для каждого узла в системе. - не нужно тестировать то, на что невозможно повлиять. Это предварительный контекст, который можно просто проверить. - т.н. принцип Exhaustive testing is impossible - все проверить невозможно. Но к этому надо стремиться ![]() - тестировать нужно на наиболее вероятных входных данных, которые могут ожидаться. Не стоит ждать еще год, чтобы придумать еще какие-то данные. Если это и произойдет, то об этом сообщат пользователи и можно будет подумать над проблемой. - defects clustering: как правило, основные ошибки будут находится где-то в определенном месте, а не разбросаны по всем методам. - излишнее тестирование может привести к проблеме пестицидов: эти тесты будут не способны выявить новые проблемы.
1
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
||
| 09.06.2025, 23:42 [ТС] | ||
|
Внутри да, этот метод структурирован и разбит на логичные части, каждая со своей зоной ответственности. Но обозначенный public-метод 'Parse' делает ровно то, что от него требуется - переребатывает сложный массив входных данных в другой массив данных.
0
|
||
|
|
||
| 09.06.2025, 23:45 | ||
|
Наверное, будет все проще, если быть уверенным в основной массе его кода..
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|
| 09.06.2025, 23:47 [ТС] | |
|
Хотя, наверное, в приведённом выше примере можно выкрутиться следующим образом:
1. Протестировать по отдельности все три приватных метода. Для каждого в отдельности тесты (и тестовые данные) будут куда проще, чем при тестировании всего вместе. 2. А для метода 'Parse' реализовать простой тест, который просто проверит, что внутри реально выполняются все шаги. Для этого будет достаточно самого минимума входных данных. Т.е. оно не проверит, что логика 'Filter' корректна во всех деталях (для этого есть другой тест), но проверит, что 'Filter' в принципе был вызван по отсутствию в выходных данных определённых значений.
0
|
|
|
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
|
|
| 10.06.2025, 00:38 | |
|
0
|
|
|
|
|||||||
| 10.06.2025, 08:40 | |||||||
#if, и в ней менять доступ к методу для теста на public, для релиза на private. И тогда можно будет подключится тестовой сборкой к классу, а в релиз не попадёт ненужный код.
1
|
|||||||
|
|
||
| 10.06.2025, 10:46 | ||
|
0
|
||
|
|
||
| 10.06.2025, 10:52 | ||
|
1. Создал конфиг для компилятора. 2. Сделал #if где нужно.3. Сделал внешнюю сборку для тестов, подключил. 4. Написал тест. И потом только переключаешь конфиги сборки и работаешь
1
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|||||||
| 10.06.2025, 11:46 [ТС] | |||||||
|
Добавлено через 3 минуты
0
|
|||||||
|
|
|
| 10.06.2025, 12:24 | |
|
Если пишешь сам и есть исходники, то какой смысл так заморачиваться в принципе?
Тестирование имеет смысл только для публичных методов. Особенно(!), если эти тесты передаются кому-то вместе с кодовой базой. Ну сделал временно public, прогнал тестов кучу, все работает - ок, за-private-л класс/метод обратно и забыл. Так же, у классов могут быть интерфейсы: кто мешает создать экземпляр через интерфейс и тестировать его методы как черный ящик? Не показывая никому реализаций..
2
|
|
| 10.06.2025, 12:24 | |
|
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), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
|