- Как вы думаете, может ли имитация моей базы данных «скрыть» ошибки, которые могут возникнуть только тогда, когда мой код работает с реальной базой данных? Обратите внимание, что я не хочу тестировать Entity Framework (я уверен, что замечательные люди из Microsoft отлично с этим справились), но сможет ли мой код хорошо работать против фиктивных и взломов MySQL?
Да, если вы тестируете свой код только с помощью Mocks, вам очень легко получить ложную уверенность в своем коде. Когда вы издеваетесь над базой данных, вы говорите: «Я ожидаю, что эти вызовы будут иметь место». Если ваш код делает такие вызовы, он пройдет тест, но если это неправильные вызовы, он не будет работать в рабочей среде. На простом уровне, если вы добавляете/удаляете столбец из своей базы данных, взаимодействие с базой данных может измениться, но процесс добавления/удаления столбца скрыт от ваших тестов, пока вы не обновите макеты.
- Считаете ли вы, что переход от интеграционного тестирования к модульному тестированию — это король «понижения»?
Это не понижение, это другое. Модульное тестирование и интеграционное тестирование имеют разные преимущества, которые в большинстве случаев дополняют друг друга.
- Считаете ли вы, что отказаться от интеграционного тестирования и принять модульное тестирование из соображений скорости — это нормально?
Хорошо, это очень субъективно. Я бы сказал нет, однако вам не нужно запускать все тесты все все время. Большинство сред тестирования (если не все) позволяют вам тем или иным образом классифицировать ваши тесты. Это позволяет вам создавать подмножества ваших тестов, так что вы можете, например, иметь категорию «DatabaseIntegration», в которую вы помещаете все свои тесты интеграции с базой данных, или «EndToEnd» для полных сквозных тестов. Мой предпочтительный подход - иметь отдельные сборки. Обычная/непрерывная сборка, которую я запускаю до/после каждой регистрации, запускает только модульные тесты. Это дает быструю обратную связь и подтверждение того, что ничего не сломалось. Менее распространенная / ежедневная / ночная сборка, в дополнение к запуску модульных тестов, также будет выполнять более медленные / повторяющиеся интеграционные тесты. Я бы также предпочел запустить интеграционные тесты для областей, над которыми я работал, прежде чем проверять код, если есть вероятность того, что код повлияет на интеграцию.
- Я знаю, что существует какой-то фреймворк, который запускает тесты для базы данных в памяти (например, фреймворк Effort), но я не вижу преимуществ этого по сравнению с имитацией, что я упускаю?
Я не использовал их, так что это предположение. Я бы предположил, что основное преимущество заключается в том, что вместо того, чтобы моделировать взаимодействие с базой данных с помощью макетов, вы вместо этого настраиваете базу данных и измеряете состояние публикации. Тесты становятся менее как вы что-то сделали и больше какие данные переместились. На первый взгляд, это может привести к менее хрупким тестам, однако вы фактически пишете интеграционные тесты для другого поставщика данных, который вы не собираетесь использовать в рабочей среде. Правильно ли это, опять же, очень субъективно.
Я предполагаю, что второе преимущество, вероятно, заключается в том, что вам не обязательно нужно реорганизовывать свой код, чтобы воспользоваться преимуществами базы данных в памяти. Если ваш код не был создан для поддержки внедрения зависимостей, есть большая вероятность, что вам потребуется выполнить некоторый уровень рефакторинга для поддержки имитации.
Я также знаю, что в идеальном мире я бы сделал и то, и другое (тесты с использованием моков и с использованием базы данных), но у меня нет на это времени.
Я действительно не понимаю, почему вы считаете, что это так. Вы уже сказали, что у вас уже есть интеграционные тесты, которые вы планируете заменить модульными тестами. Если вам не нужно проводить серьезный рефакторинг для поддержки модульных тестов, ваши интеграционные тесты должны работать. Обычно вам не нужно столько интеграционных тестов, сколько модульных тестов, поскольку модульные тесты предназначены для проверки функциональности, а интеграционные тесты — для проверки интеграции, поэтому накладные расходы на их создание должны быть относительно небольшими. Использование категоризации для определения того, какие тесты вы выполняете, сократит время, затрачиваемое на выполнение ваших тестов.
В качестве побочного вопроса, какой инструмент вы бы порекомендовали для насмешек. Мне сказали, что «moq» — хороший фреймворк, но немного медленный. Как вы думаете?
Я использовал довольно много разных библиотек для насмешек, и по большей части все они очень похожи. Некоторые вещи проще с другими фреймворками, но, не зная, что вы делаете, трудно сказать, заметите ли вы это. Если вы не создали свой код с учетом внедрения зависимостей, возможно, вам будет сложно доставить ваши макеты туда, где они вам нужны.
Насмешка любого рода, как правило, довольно быстрая, вы обычно (если вы не используете частичные моки) удаляете всю функциональность класса/интерфейса, который вы имитируете, поэтому он будет работать быстрее, чем ваш обычный код. Единственные проблемы с производительностью, о которых я слышал, - это если вы используете подделки/прокладки MS, иногда (в зависимости от сложности подделываемой сборки) создание поддельных сборок может занять некоторое время.
Два фреймворка, которые я использовал, немного отличаются друг от друга: подделки/прокладки MS и Typemock. Версия MS требует определенного уровня визуальной студии, но позволяет создавать поддельные сборки с прокладками определенных типов объектов, что означает, что вам не нужно передавать свои макеты из теста туда, где они используются. Typemock — это коммерческое решение, которое использует API профилирования для внедрения кода во время выполнения ваших тестов, что означает, что оно может достигать тех частей, которые не могут другие фреймворки. Они оба особенно полезны, если у вас есть кодовая база, которая не была написана с учетом модульного тестирования, которое может помочь преодолеть разрыв.
person
forsvarir
schedule
02.07.2015