Плохо ли проводить тесты в базе данных, а не в поддельных репозиториях? - PullRequest
13 голосов
/ 03 марта 2009

Я знаю, в чем преимущества, и использую фальшивые данные, когда работаю с более сложными системами.

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

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

Когда я говорю «настоящая база данных», я имею в виду не производственную базу данных, я имею в виду тестовую базу данных, но использую реальную действующую СУБД и ту же схему, что и настоящая база данных.

Ответы [ 11 ]

20 голосов
/ 05 марта 2009

Причины использования поддельных данных вместо реальной БД:

  1. Скорость. Если ваши тесты медленные, вы не собираетесь их запускать. Пересмотр базы данных может сделать ваши тесты намного быстрее, чем они могли бы.
  2. Контроль. Ваши тесты должны быть единственным источником ваших тестовых данных. Когда вы используете поддельные данные, ваши тесты выбирают, какие подделки вы будете использовать. Таким образом, нет никаких шансов, что ваши тесты будут испорчены, потому что кто-то оставил БД в незнакомом состоянии.
  3. Орден Независимости. Мы хотим, чтобы наши тесты работали в любом порядке. Ввод одного теста не должен зависеть от вывода другого. Когда ваши тесты контролируют данные теста, тесты могут быть независимыми друг от друга.
  4. Независимость окружающей среды. Ваши тесты должны выполняться в любой среде. Вы должны иметь возможность управлять ими, находясь в поезде, самолете, дома или на работе. Они не должны зависеть от внешних услуг. Когда вы используете поддельные данные, вам не нужна внешняя БД.

Теперь, если вы создаете небольшое маленькое приложение и, используя реальную БД (например, MySQL), вы можете достичь вышеуказанных целей, тогда непременно используйте БД. Я делаю. Но не заблуждайтесь, поскольку ваше приложение растет, в конечном итоге вы столкнетесь с необходимостью макетирования БД. Это нормально, делай это, когда тебе нужно. YAGNI. Просто убедитесь, что вы делаете это, когда вам нужно. Если вы отпустите, вы заплатите.

2 голосов
/ 03 марта 2009

Я думаю, это зависит от того, зафиксированы ли ваши запросы внутри хранилища (лучший вариант, IMO), или же хранилище предоставляет составные запросы; например - если у вас есть метод репозитория:

IQueryable<Customer> GetCustomers() {...}

Тогда ваш пользовательский интерфейс может запросить:

var foo = GetCustomers().Where(x=>SomeUnmappedFunction(x));

bool SomeUnmappedFunction(Customer customer) {
   return customer.RegionId == 12345 && customer.Name.StartsWith("foo");
}

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

Customer[] GetCustomers(int? regionId, string nameStartsWith, ...) {...}

Поскольку это не может быть скомпоновано, вы можете проверить DB и UI независимо. В случае составных запросов вы вынуждены использовать интеграционные тесты, если хотите, чтобы они были полезны.

2 голосов
/ 03 марта 2009

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

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

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

Сказав это, если вы действительно хотите проверить свою базу данных, вы можете. Существуют инструменты, которые помогают настраивать и разрушать базу данных, например dbunit .

Я видел людей, пытающихся создать модульный тест, подобный этому, но почти всегда оказывается гораздо больше работы, чем оно того стоит. Большинство оставило его на полпути во время проекта, большинство отказалось от ттд полностью во время проекта, думая, что опыт переносится на модульное тестирование в целом.

Поэтому я бы рекомендовал держать тесты простыми и изолированными и инкапсулировать ваш код достаточно хорошо, чтобы стало возможным тестировать ваш код изолированно.

1 голос
/ 03 марта 2009

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

В юнит-тесте «тест» важнее, чем «юнит».

1 голос
/ 03 марта 2009

Это нормально для сценария, если вы не рассматриваете его как «модульные» тесты. Это были бы интеграционные тесты. Вы также хотите решить, будете ли вы снова и снова проводить тестирование через пользовательский интерфейс вручную, поскольку вместо этого вы можете просто автоматизировать свои тесты дыма. Учитывая это, вы можете даже не рассматривать интеграционные тесты, а просто работать на уровне функциональных тестов / тестов пользовательского интерфейса (так как они уже будут охватывать интеграцию).

Как уже отмечалось, трудно провести черту над сложным / не сложным, и вы обычно делаете это сейчас, когда уже слишком поздно :(. Если вы уже привыкли делать это, я уверен, что вы победили Это может привести к большим накладным расходам. Если бы это было не так, вы могли бы извлечь уроки из этого:)

1 голос
/ 03 марта 2009

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

Однако есть несколько недостатков:

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

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

1 голос
/ 03 марта 2009

Если вы просто пишете простое одноразовое приложение, которое, как вы знаете, не будет расти, я думаю, что многие "лучшие практики" просто уйдут в окно.

Вам не требуется для использования DI / IOC, модульных тестов или макета доступа к БД, если все, что вы пишете, - это простая форма «Свяжитесь с нами». Однако трудно провести черту между «простым» и «сложным» приложениями.

Другими словами, используйте свое лучшее суждение, так как нет точного ответа на это.

1 голос
/ 03 марта 2009

Это скорее зависит от того, будет ли БД автоматически настроена тестом, а также от того, изолирована ли база данных от других разработчиков.

На данный момент это может не быть проблемой (например, только один разработчик). Однако (для ручной настройки базы данных) настройка базы данных является дополнительным препятствием для запуска тестов, и это очень плохо.

0 голосов
/ 03 марта 2009

Недостатками запуска тестов для вашей базы данных являются недостаточная скорость и сложность настройки состояния базы данных перед запуском тестов.

Если у вас есть контроль над этим, нет проблем в запуске тестов непосредственно для базы данных; на самом деле это хороший подход, потому что он симулирует ваш конечный продукт лучше, чем использование поддельных данных. Ключ должен иметь прагматичный подход и рассматривать лучшую практику как руководство, а не как правило.

0 голосов
/ 03 марта 2009

Одним из преимуществ поддельных репозиториев является то, что ваше регрессионное / модульное тестирование является последовательным, поскольку вы можете ожидать одинаковых результатов для одинаковых запросов. Это облегчает создание определенных модульных тестов.

Есть несколько недостатков, если ваш код (если не только запрос на чтение) изменяет данные: - Если у вас есть ошибка в вашем коде (возможно, именно поэтому вы тестируете), вы можете в итоге сломать производственную базу данных. Даже если ты не сломал это. - если производственная база данных изменяется со временем и особенно во время выполнения вашего кода, вы можете потерять отслеживание добавленных вами тестовых материалов и впоследствии испытать трудности с их удалением из базы данных. - Производственные запросы из других систем, обращающихся к базе данных, могут рассматривать ваши тестовые данные как реальные данные, и это может повредить результаты важных бизнес-процессов где-то в будущем. Например, даже если вы пометили свои данные определенным флагом или префиксом, можете ли вы гарантировать, что любой, кто обращается к базе данных, будет придерживаться этой схемы?

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

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

...