2010-06-26 6 views
3

This question about unit tests зажег другую вещь, которая меня беспокоила. Я пошел туда и обратно по трем способам выполнения модульных тестов при попадании в базу данных.Единичные тесты и база данных

  1. Создайте имитирующие объекты и подключите их. Это имеет то преимущество, что вам не нужна база данных, но это занимает много времени, и я не уверен, сколько возврата инвестиций я получаю. Я немного вхожу в МОК и moq, но это все еще кажется болезненным.
  2. Создайте сценарии базы данных настройки и разрыва для создания известных случаев и проверьте их. Опять же, это может быть трудоемким, но все же легче создавать, чем макет объектов большую часть времени. И другие люди на работе все еще могут работать, полагая, что у них есть SQL-сервер на своем локальном хосте.
  3. Вручную проверьте базу данных разработчиков и измените модульные тесты. Интенсивно ручная работа, но если у меня есть «тестовый набор», который не меняется, он, похоже, работает нормально. На моей машине, по крайней мере :-).

Я знаю, что вариант 1 - это «правильный» способ проведения модульных тестов, но из трех, это, вероятно, вариант, который я использовал наименее (хотя последние проекты были с IOC, так что дверь открыт для меня). Я понимаю, что многое зависит от того, что именно издевается и что тестируется, но чего я здесь не хватает?

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

+0

Техника № 3 (автоматизация выполнения SUT, но проверка результатов вручную) полезна для тестирования вещей, которые не могут быть действительно проверены автоматически, например аспекты внешнего вида пользовательского интерфейса, внешний вид HTML в разных браузерах или обеспечение ваша игра имеет хорошую графику. Однако с базами данных, я думаю, вы потратите меньше времени на тестирование в целом, используя вместо этого первые 2 метода. – apollodude217

+0

Разве это не дура? http://stackoverflow.com/questions/3111645/mock-objects-vs-test-database –

ответ

3

Первым не должно быть так сложно, если у вас есть уровень доступа к данным, который предоставляет только несколько методов IQueryable<T>. Есть хороший трюк, который вы можете использовать для поддельных данных: просто сохраните объекты сущности в List<T> и используйте AsQueryable. Я нахожу это проще, чем moq для частей данных.

Что касается МОК, я считаю, что в настоящее время он злоупотребляет (помните, что мое мнение представляет меньшинство программистов в этом отношении). Вы можете использовать инструмент, например Moles, во время тестирования, чтобы издеваться, не нарушая дизайн вашей программы. Я не использую IOC, если дизайн на самом деле не требует этого.

1

Существует целый набор ответов на этот вопрос. Первое, что нужно сделать, это четко сформулировать то, что вы тестируете. Это фасад API, который имеет за собой базу данных, объекты DAO, структуру вашей базы данных?

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

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

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

2

Я бы определенно продолжал использовать настоящие модульные тесты (вариант 1). Мне нравится совет Стивена.

Вы также можете найти интеграционные тесты с реальной базой данных (опция 2) необходимо использовать также (вариант 2). Зачем? Потому что часть того, что вам нужно проверить (сопоставление O/R, совместимость с фактической схемой БД и т. Д.), Не покрываются настоящими модульными тестами.

Что касается установки и демонтажа логики, унаследовав от этого обычно достаточно (с использованием .NET, NUnit и SqlServer для базы данных):

using System.Transactions; 
using NUnit.Framework; 
namespace Crown.Util.TestUtil 
{ 
    [TestFixture] 
    public class PersistenceTestFixture 
    { 
     public TransactionScope TxScope { get; private set; } 

     [SetUp] 
     public void SetUp() 
     { 
      TxScope = new TransactionScope(); 
     } 

     [TearDown] 
     public void TearDown() 
     { 
      if (TxScope != null) 
      { 
       TxScope.Dispose(); 
       TxScope = null; 
      } 
     } 
    } 
} 

Легкий как пирог.

0

Что вы испытываете на самом деле, что заставляет вас чувствовать, что это сложно?

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

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

Смежные вопросы