Легкие приемочные испытания со спецификацией

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

IEnumerable<MyClass> userInterfaceElements = ...
IQueryable<MyClass> databaseElements = ...

Примечание: запрос еще не выполнен!

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

  • Элементы пользовательского интерфейса, которых еще нет в базе данных, будут добавлены
  • Элементы базы данных, которых нет в пользовательском интерфейсе, должны быть удалены
  • Элементы пользовательского интерфейса которые также в базе данных должны быть обновлены.

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

var itemsToAdd = userInterfaceElements.Where(row => row.Id == 0);
var itemsToUpdate = userInterfaceElements.Where(row => row.Id != 0);

var idsItemsToKeep = itemsToUpdate.Select(row => row.Id);
var itemsToRemove = databaseElements.Where(row => !idsItemsToKeep.Contains(row.Id))

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

Примечание К настоящему времени вы запросили базу данных ровно один раз: вы выбрали все элементы для удаления. Вы не можете заказать структуру сущностей для удаления элементов без предварительной загрузки их.

dbContext.MyClasses.RemoveRange(removeList);
dbContext.MyClasses.AddRange(addList);

Для обновления в объектной структуре правильным методом будет выборка данных, а затем изменение свойств.

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

Правильный путь:

foreach(var itemToUpdate in updateList)
{
     var fetchedItem = dbContext.MyClasses.Find(itemToUpdate.Id);
     // TODO: update changed properties of the fetchedItem with values from itemToUpdate
}

Опасный метод:

foreach(var itemToUpdate in updateList)
{
    dbContext.Entry(itemToUpdate).State = entityState.Modified;
}

Наконец:

dbContext.SaveChanges();

Улучшен метод удаления

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

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

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

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

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

Хорошая вещь об устаревшем состоит в том, что, если кто-то объявил элемент устаревшим случайно, еще есть некоторое время, чтобы исправить это.

7
задан Mnementh 21 July 2009 в 13:35
поделиться

5 ответов

http://fitnesse.org/, кажется, соответствует всей квалификации, которую Вы хотите. Это - то, которое я использовал с успехом.

7
ответ дан 6 December 2019 в 23:16
поделиться

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

1
ответ дан 6 December 2019 в 23:16
поделиться

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

1
ответ дан 6 December 2019 в 23:16
поделиться

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

Коммерческое применение, такое как HP Quick Test Pro не является достаточно нетехническим и требует дополнительной платформы такой как один из Сонета, который является шагом в правильном направлении, но ни один не открытый исходный код или основанный на Java.

Даже с платформой на месте, это - довольно мало работы для создания этой работы автоматизированным способом. Я хотел бы, чтобы Вы полагали, что время должно было разработать платформу по сравнению со временем для ручного запущения этих тестов и проверить использование времени хорошо.

0
ответ дан 6 December 2019 в 23:16
поделиться

Как насчет Cucumber:

Feature: Acceptance testing framework

  Scenario: an example speaks volumes
    Given a text example
    When it is read
    Then the simplicity will be appreciated

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

Given /^a text example$/ do
  file.open("example.txt", "w") { |file| file.write "text example" }
end

When /^it is read$/ do
  SystemUnderTest.read("example.txt")
end

Then /^the simplicity will be appreciated$/ do
  SystemUnderTest.simplicity.should be_appreciated
end
0
ответ дан 6 December 2019 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: