У меня есть кусок кода, который выглядит примерно так:
function bool PassesBusinessRules()
{
bool meetsBusinessRules = false;
if (PassesBusinessRule1
&& PassesBusinessRule2
&& PassesBusinessRule3)
{
meetsBusinessRules= true;
}
return meetsBusinessRules;
}
Я считаю, что должно быть четыре модульных теста для этой конкретной функции. Три, чтобы проверить каждое из условий в операторе if и убедиться, что оно возвращает false. И еще один тест, который проверяет, что функция возвращает true.
Вопрос: Должно ли на самом деле быть десять юнит-тестов? Девять, которая проверяет каждый из возможных путей отказа. IE:
- Ложь Ложь Ложь
- Ложь Ложь Истина
- Ложь верно ложь
И так далее для каждой возможной комбинации.
Я думаю, что это излишне, но некоторые другие члены моей команды этого не делают. Я смотрю на это так: если BusinessRule1 дает сбой, он всегда должен возвращать false, не имеет значения, проверен ли он первым или последним.
unit-testing
bwalk2895
источник
источник
Ответы:
Формально эти типы покрытия имеют имена.
Во-первых, есть предикатное покрытие : вы хотите иметь тестовый пример, который делает оператор if истинным, и такой, который делает его ложным. Выполнение этого покрытия, вероятно, является основным требованием для хорошего набора тестов.
Затем есть условие покрытия : здесь вы хотите проверить, что каждое подусловие в if имеет значение true и false. Это, очевидно, создает больше тестов, но, как правило, выявляет больше ошибок, поэтому, если у вас есть время, часто рекомендуется включать их в свой набор тестов.
Наиболее продвинутый критерий покрытия обычно называется охватом комбинаторных условий : здесь цель состоит в том, чтобы создать контрольный пример, который проходит через все возможные комбинации логических значений в вашем тесте.
Это лучше, чем простой предикат или условие покрытия? С точки зрения покрытия, конечно. Но это не бесплатно. Это очень дорого обходится при проведении испытаний. По этой причине большинство людей не беспокоятся о полном комбинаторном охвате. Обычно тестирование всех веток (или всех условий) будет достаточно для выявления ошибок. Добавление дополнительных тестов для комбинаторного тестирования обычно не выявляет больше ошибок, но требует много усилий для создания и поддержки. Дополнительные усилия, как правило, делают это не стоящим очень-очень небольшой отдачи, поэтому я бы не рекомендовал это.
Часть этого решения должна основываться на том, насколько рискованным вы считаете этот код. Если у него много места для неудачи, стоит попробовать. Если он несколько стабилен и не сильно изменится, вам следует сосредоточить свои усилия на тестировании в другом месте.
источник
В конечном счете, это зависит от вас (вашей команды), кода и конкретной среды проекта. Универсального правила не существует. Вы (команда) должны написать столько тестов, сколько вам нужно, чтобы чувствовать себя комфортно, чтобы код действительно был правильным . Так что если ваши товарищи по команде не убеждены 4 тестами, возможно, вам нужно больше.
Время для написания юнит-тестов обычно ограничено Поэтому постарайтесь найти лучший способ провести ограниченное время, которое у вас есть . Например, если у вас есть другой важный метод с охватом 0%, может быть лучше написать пару модульных тестов, чтобы охватить этот, а не добавлять дополнительные тесты для этого метода. Конечно, это также зависит от того, насколько хрупкой является реализация каждого из них. Планирование большого количества изменений этого конкретного метода в обозримом будущем может оправдать дополнительное покрытие модульных тестов. Так может быть на критическом пути внутри программы. Это все факторы, которые могут оценить только вы (команда).
Я лично был бы счастлив с 4 тестами, которые вы наметили, а именно:
плюс может быть один:
чтобы гарантировать, что единственный способ получить возвращаемое значение
true
- это выполнить все 3 бизнес-правила. Но, в конце концов, если ваши товарищи по команде настаивают на том, чтобы комбинаторные пути были покрыты, может быть дешевле добавить эти дополнительные тесты, чем продолжать спор намного дольше :-)источник
Если вы хотите быть в безопасности, вам понадобится восемь модульных тестов с использованием условий, представленных таблицей истинности с тремя переменными ( http://teach.valdosta.edu/plmoch/MATH4161/Spring%202004/and_or_if_files/image006.gif ).
Вы никогда не можете быть уверены, что бизнес-логика всегда будет предусматривать, что проверки выполняются в таком порядке, и вы хотите, чтобы тест знал как можно меньше о фактической реализации.
источник
Да, в идеальном мире должна быть полная комбинация.
Выполняя модульное тестирование, вы действительно должны стараться игнорировать, как метод работает. Просто предоставьте 3 входа и убедитесь, что выход правильный.
источник
Государство это зло. Следующая функция не нуждается в модульном тестировании, потому что она не имеет побочных эффектов и хорошо понимает, что она делает, а что нет. Зачем это проверять? Ты не доверяешь своему мозгу ??? Статические функции великолепны!
источник
a
,b
иc
. Вы можете перемещать бизнес-логику по своему усмотрению, в конце концов вам все равно нужно где-то ее протестировать.Я знаю, что этот вопрос довольно старый. Но я хочу дать другую точку зрения на проблему.
Во-первых, ваши юнит-тесты должны иметь две цели:
what's the class' intention
иhow the class is doing its work
Итак, подытоживая проблему, мы хотим протестировать
complex if statement
, для данного примера есть 2 ^ 3 возможности, то есть большое количество тестов, которые мы можем написать.what is doing the code
С другой стороны, если вы находитесь в положении, когда ваши тесты даже более сложны, чем реализация, то это потому, что реализация должна быть переработана (более или менее в зависимости от случая), а не сам тест.
Например, для сложных операторов if можно подумать о шаблоне цепочечной ответственности , реализуя каждый обработчик следующим образом:
If some simple business rule apply, derive to the next handler
Насколько просто было бы протестировать различные простые правила вместо сложных правил?
Надеюсь, это поможет,
источник
Это один из тех случаев, когда что-то вроде quickcheck ( http://en.wikipedia.org/wiki/QuickCheck ) станет вашим другом. Вместо того чтобы писать все N случаев вручную, компьютер сгенерирует все (или, по крайней мере, большое количество) возможных тестовых случаев и подтвердит, что все они дают разумный результат.
Мы программируем компьютеры для жизни здесь, почему бы не запрограммировать компьютер для генерации ваших тестовых случаев для вас?
источник
Вы можете изменить условия в охранные условия:
Я не думаю, что это уменьшает количество случаев, но мой опыт показывает, что легче разбить их таким образом.
(Обратите внимание, что я большой поклонник "единой точки выхода", но я делаю исключение для условий защиты. Но есть и другие способы структурировать код, чтобы у вас не было отдельных возвратов.)
источник