Пожалуйста, смотрите код ниже; Он проверяет, имеет ли право лицо с Полом женщины на предложение1:
[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
var personId = Guid.NewGuid();
var gender = "F";
var person = new Person(personId, gender);
var id = Guid.NewGuid();
var offer1 = new Offer1(id,"Offer1");
Assert.False(offer1.IsEligible(person));
}
Этот модульный тест пройден успешно. Тем не менее, он потерпит неудачу, если «Предложение1» будет предложено женщинам в будущем.
Допустимо ли говорить - если бизнес-логика, окружающая предложение 1, изменится, тогда должен измениться модульный тест. Обратите внимание, что в некоторых случаях (для некоторых предложений) бизнес-логика изменяется в базе данных следующим образом:
update Offers set Gender='M' where offer=1;
и в некоторых случаях в модели предметной области, как это:
if (Gender=Gender.Male)
{
//do something
}
Обратите также внимание на то, что в некоторых случаях логика домена, предлагаемая за этим, регулярно меняется, а в некоторых - нет.
c#
unit-testing
domain-driven-design
xunit
w0051977
источник
источник
Ответы:
Это не хрупкий в обычном смысле. Модульный тест считается хрупким, если он ломается из-за изменений реализации, которые не влияют на тестируемое поведение. Но если сама бизнес-логика изменится, то тест этой логики должен прерваться.
Тем не менее, если бизнес-логика действительно часто меняется, возможно, нецелесообразно жестко кодировать ожидания в модульных тестах. Вместо этого вы можете проверить, влияют ли конфигурации в базе данных на предложения, как ожидалось.
Название теста
Returns False When Given A Person With A Gender Of Female
не описывает бизнес-правило. Бизнес-правило было бы что-то вродеOffers Applicable to M should not be applied to persons of gender F
.Таким образом, вы можете написать тест, который подтверждает, что если предложение определено как применимое только к лицам типа M, то лицо типа F не будет указано в качестве отвечающего критериям. Этот тест обеспечит работу логики даже в случае изменения конфигурации конкретных предложений.
источник
Когда свойство определено в производственной базе данных (или клоне для тестирования), это не модульный тест . Юнит-тест проверяет единицу работы и не требует определенного внешнего состояния для работы. Это предполагает, что
Offer1
в базе данных определено предложение только для мужчин. Это внешнее состояние. Так что это скорее интеграционный тест , а именно тест системы или приемочный тест. Обратите внимание, что приемочные тесты часто не пишутся в сценарии (не запускаются в тестовой среде, а выполняются вручную людьми).Когда свойство определяется в модели предметной области с помощью
if
оператора, этот же тест является модульным тестом. И это может быть хрупким. Но настоящая проблема в том, что код хрупок. Как правило, ваш код будет более устойчивым, если бизнес-поведение настраивается, а не жестко запрограммировано. Потому что быстрое развертывание для исправления небольшой ошибки кодирования должно быть редким. Но деловое требование, изменяющееся без уведомления, - это просто вторник (то, что происходит еженедельно).Возможно, вы используете модуль модульного теста для запуска теста. Но рамки модульных тестов не ограничиваются выполнением модульных тестов. Они могут и действительно выполнять интеграционные тесты.
Если бы вы писали модульный тест, вы бы создали и то
person
и другоеoffer1
с нуля, не полагаясь на состояние базы данных. Что-то типаОбратите внимание, что это не меняется в зависимости от бизнес-логики. Это не утверждение, что
offer1
отвергает женщин. Это делаетoffer1
предложение, которое отвергает женщин.Вы можете создать и настроить базу данных как часть теста. В C #, используя NUnit или в Java JUnit, вы бы настраивали базу данных в
Setup
методе. Предположительно, ваша тестовая среда имеет аналогичное понятие. В этом методе вы можете вставлять записи в базу данных с помощью SQL.Если вам трудно писать код, который заменяет тестовую базу данных для рабочей базы данных, это звучит как слабость тестирования в вашем приложении. Для тестирования было бы лучше использовать что-то вроде внедрения зависимостей, которое допускает подстановку. Затем вы можете написать тесты, которые не зависят от текущих бизнес-правил.
Дополнительным преимуществом этого является то, что владельцу бизнеса часто проще (не обязательно корпоративному владельцу, а скорее человеку, ответственному за этот продукт в корпоративной иерархии) настраивать бизнес-правила напрямую. Потому что, если у вас есть такая техническая структура, владельцу бизнеса легко разрешить использовать пользовательский интерфейс (UI) для настройки предложения. Владелец бизнеса выберет ограничение в пользовательском интерфейсе и выдаст
markLimitedToGender("M")
вызов. Затем, когда предложение сохраняется в базе данных, оно будет хранить это. Но вам не нужно хранить предложение использовать его. Таким образом, ваши тесты могут создать и настроить предложение, которого нет в базе данных.В вашей системе, как описано, владелец бизнеса должен будет отправить запрос технической группе, которая выдаст соответствующий SQL и обновит тесты. Или техническая группа должна отредактировать ваш код и тесты (или тесты, а затем код). Это кажется довольно тяжелым подходом. Ты можешь это сделать. Но ваше программное обеспечение (а не только тестирование) было бы менее хрупким, если бы вам не пришлось это делать.
TL; DR : вы можете писать такие тесты, но вам лучше писать свои программы, так что вам не нужно это делать.
источник