Несколько утверждений плохо в модульном тесте?Даже если цепочки? - PullRequest
39 голосов
/ 12 марта 2010

Что-то не так с проверкой многих вещей в этом модульном тесте?:

ActualModel = ActualResult.AssertViewRendered()        // check 1
                          .ForView("Index")            // check 2
                          .WithViewData<List<Page>>(); // check 3

CollectionAssert.AreEqual(Expected, ActualModel);      // check 4

Основными целями этого теста являются проверка правильности представления (проверка 2) и содержит правильные данные (проверка 4).

Получу ли я что-нибудь, разделив это на несколько тестов? Я все делаю правильно, но я не собираюсь делить вещи, если это не имеет практической ценности.

Я довольно новичок в модульном тестировании, так что будьте осторожны.

Ответы [ 6 ]

29 голосов
/ 12 марта 2010

Как уже отмечали другие, лучше придерживаться одного утверждения в каждом тесте, чтобы не потерять информацию - если первое утверждение не удастся, вы не знаете, будут ли также и более поздние. Вы должны решить проблему с помощью меньшего количества информации - что может (вероятно, будет) сложнее.

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

12 голосов
/ 08 мая 2014

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

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

8 голосов
/ 12 марта 2010

Пока каждое утверждение имеет уникальное и идентифицирующее сообщение об ошибке, вы должны быть в порядке и обойти любые проблемы рулетки утверждений, потому что нетрудно определить, какой тест не удался. Используй здравый смысл.

7 голосов
/ 11 февраля 2015

Я нашел другой аргумент к этому вопросу (по крайней мере, для себя):

Можно использовать несколько утверждений, если они проверяют одно и то же.

Например, все в порядке:

Assert.IsNotNull(value);
Assert.AreEqual(0, value.Count);

Почему? - потому что эти два утверждения не скрывают намерения теста. Если первое утверждение завершится неудачно, это означает, что второе тоже не удастся. И действительно, если мы удалим первое утверждение, второе утверждение завершится неудачно (с исключением нулевой ссылки - !!!) в любом случае, когда value нулевой. Если это не так, то нам не следует объединять эти два утверждения.

Итак, это неправильно:

Assert.IsNotNull(value1);
Assert.IsNotNull(value2);

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

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

2 голосов
/ 12 марта 2010

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

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

Это гарантирует, что каждый тестовый случай проверяет только одну вещь.

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

0 голосов
/ 21 августа 2015

Я знаю, что это старый вопрос, но я решил добавить свой бит.

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

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

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

Assert.AreEqual("Mr Smith", GetSalutation("Mr", "J", "Smith"));
Assert.AreEqual("Mr Smith", GetSalutation("Mr", "John", "Smith"));
Assert.AreEqual("Sir/Madam", GetSalutation("", "John", "Smith"));
Assert.AreEqual("Sir/Madam", GetSalutation("", "J", "Smith"));

Альтернативой этому является вести подсчет проблем и утверждать это в конце.

int errorCount = 0;
string result;

result = GetSalutation("Mr", "J", "Smith");
if (result == "Mr Smith")
    errorCount++;

result = GetSalutation("Mr", "John", "Smith");
if (result == "Mr Smith")
    errorCount++;

Assert.AreEqual(0, errorCount);

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

...