Подтвердить что ты не робот

Являются ли множественные утверждения плохими в unit test? Даже если цепь?

Есть ли что-то неправильное в проверке многих вещей в этом unit test?:

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

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

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

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

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

4b9b3361

Ответ 1

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

Очень хорошая рекомендация: Roy Osherove Искусство модульного тестирования - если вы хотите начать работу с Unit Testing, вы можете сделать много хуже, чем начинать здесь.

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

Например, это нормально:

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

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

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

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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

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

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

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

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, чтобы написать детали отдельных тестов, которые не смогли выйти в окно вывода