Является ли плохой практикой запускать тесты в базе данных, а не в поддельных репозиториях?

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

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

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

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


person Sruly    schedule 03.03.2009    source источник
comment
реальная БД вы имеете в виду производственную БД - или БД, использующую ту же СУБД?   -  person philant    schedule 04.03.2009
comment
Я имею в виду ту же СУБД и схему, но на тестовой БД   -  person Sruly    schedule 04.03.2009
comment
Thnx, тогда подтверждаю свой ответ.   -  person philant    schedule 05.03.2009


Ответы (11)


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

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

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

person Uncle Bob    schedule 05.03.2009
comment
Скорость - единственная проблема, которую я вижу при использовании реальной БД. Управление, независимость от порядка и независимость от среды решаются с помощью реальных баз данных. Например, убедитесь, что вы удалили базу данных перед запуском первого теста, запустите все тесты в рамках транзакций, не фиксируйте транзакции. Гораздо труднее создать фальшивую реализацию уровня базы данных, которая ведет себя достаточно похоже на реальную, чтобы писать полезные тесты, чем просто направить ваш DAL на базу данных для конкретного теста. - person binki; 29.06.2018

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

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

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

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

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

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

person DefLog    schedule 03.03.2009

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

В модульном тестировании «тест» важнее, чем «модуль».

person philant    schedule 03.03.2009
comment
Боюсь, я не согласен. Тест, который не тестирует модуль, будет труднее поддерживать, и это может привести к потере желания писать тесты. Я также утверждал, что модульное тестирование приведет к более чистому дизайну, потому что должны быть модули для тестирования. - person DefLog; 03.03.2009
comment
Я имел в виду, что лучше иметь тест, охватывающий несколько единиц, чем вообще не тестировать. Если он будет проводить модульное тестирование с реальной СУБД (но не с производственной), что изменит общий дизайн по сравнению с модульным тестированием на поддельной БД? - person philant; 04.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");
}

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

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

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

person Marc Gravell    schedule 03.03.2009

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

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

person Douglas Leeder    schedule 03.03.2009

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

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

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

person Kevin Pang    schedule 03.03.2009

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

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

person eglasius    schedule 03.03.2009

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

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

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

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

person Jared Oberhaus    schedule 03.03.2009

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

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

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

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

person Uri    schedule 03.03.2009
comment
На производственной БД тестировать конечно не буду. Я хочу протестировать тестовую базу данных на фиктивных данных. - person Sruly; 03.03.2009
comment
Это действительно было неясно из вашего вопроса, поскольку вы говорили о реальной БД, которая звучала как производственная БД. - person Uri; 03.03.2009

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

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

person Alex Fort    schedule 03.03.2009

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

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

person terjetyl    schedule 03.03.2009