#c# #unit-testing #nunit
Вопрос:
Я смотрю курс для Нунита и пришел к этому упражнению, чтобы написать метод тестирования для функции ниже
public static string GetOutput(int number)
{
if ((number % 3 == 0) amp;amp; (number % 5 == 0))
return "FizzBuzz";
if (number % 3 == 0)
return "Fizz";
if (number % 5 == 0)
return "Buzz";
return number.ToString();
}
Что я сделал, так это создал параметризованный тест, чтобы охватить все случаи, как показано ниже
[Test]
[TestCase(15 , "FizzBuzz")]
[TestCase(3, "Fizz")]
[TestCase(5, "Buzz")]
public void GetOutput_WhenCalled_ReturnString(int number , string word)
{
var result = FizzBuzz.GetOutput(number);
Assert.That(result, Is.EqualTo(word));
}
Но наставник написал каждый случай отдельным методом, как, например
public void GetOutput_NumberDivisiableNy3And5_ReturnFizzBuzz()
{
var result = FizzBuzz.GetOutput(15);
Assert.That(result, Is.EqualTo("FizzBuzz"));
}
public void GetOutput_NumberDivisiableBy3_ReturnFizz()
{
var result = FizzBuzz.GetOutput(3);
Assert.That(result, Is.EqualTo("FizzBuzz"));
}
Мой вопрос в том, почему он написал это так? имеет ли такое разделение какое-то преимущество?
или это просто личное предпочтение. Я очень новичок в модульном тестировании и Nunit
Ответ №1:
Это личное предпочтение.
Важным руководством при тестировании является то, что имена, которые вы выбираете для своих тестов, должны описывать желаемое поведение тестируемого метода для заданного ввода. Подумайте об именах тестов как о сродни исполняемой документации: «при обстоятельствах X метод должен демонстрировать поведение Y».
Использование параметризованных тестов означает, что имя теста по самой своей природе менее описательно, что затрудняет определение с первого взгляда того, что именно не работает-вам нужно посмотреть параметры теста, чтобы определить случай сбоя, так как имя теста не предоставляет вам эту информацию.
Это очевидно даже в вашей реализации: в вашем имени теста говорится, что он «возвращает строку» «при вызове«. Что технически правильно, но не является описательным. Какую строку он должен возвращать при вызове с заданным значением?
С другой стороны, отдельные тестовые примеры очень четко показывают желаемое поведение: число, кратное 3 и 5, должно возвращать «шипучку» и так далее.
Кроме того, подумайте об этом так: что произойдет, если вас попросят вернуться к этому методу и развернуть его для печати Fuzz, когда число делится на 7? А Бизнес, когда делится на 9? И так далее. Ваш единственный метод тестирования может выполнить всю эту тяжелую работу, но чем больше у вас требований, тем больше нагрузки ложится на этот единственный тестовый пример и тем труднее становится четко определить, какие сценарии терпят неудачу и почему.
Ваш подход не ошибочен, но если бы я писал эти тесты, я бы написал один тестовый пример для каждого сценария: Шипение, жужжание, шипение, и ни на что не делимое.
Каждый тестовый случай все еще может быть параметризован, поэтому вы можете протестировать большее количество значений, удовлетворяющих каждому тестовому случаю.
Ответ №2:
По сути, это личные предпочтения. Однако, когда метод, который вы тестируете, принимает аргумент, кажется очень естественным использовать параметризованный тест. ОТО, не используйте параметризованный тест для написания теста для двух или более совершенно разных вещей… на самом деле, вообще не пишите тест более чем для одной цели за раз!
Я предполагаю, что ваш преподаватель пытается начать с фундаментального подхода и представит параметризованные тесты только на более позднем уроке. Но, конечно, это только предположение.