Как предотвратить «чрезмерное тестирование» в тестовом случае?(С # / NUnit) - PullRequest
7 голосов
/ 23 июля 2010

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

[Test]
public void TestNamePropertyCorrectlySetOnInstantiation()
{
  MyClass myInstance = new MyClass("Test name");
  Assert.AreEqual("Test Name", myInstance.Name);
}

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

Я рефакторинг это так:

[Test]
public void TestNamePropertyCorrectlySetOnInstantiation()
{
  MyClass myInstance;
  string namePropertyValue;

  Assert.DoesNotThrow(() => myInstance = new MyClass("Test name"));
  Assert.DoesNotThrow(() => namePropertyValue = myInstance.Name);
  Assert.AreEqual("Test Name", namePropertyValue);
}

но, конечно, сейчас я на самом деле тестирую три вещи здесь; В этом тесте меня не интересует проверка того, был ли успешно создан экземпляр MyClass или что свойство Name было прочитано успешно, они проверяются в другом случае. Но как я могу проверить последнее утверждение, не утвердив сначала два других, учитывая, что невозможно даже выполнить тест, если первые два не пройдены?

Ответы [ 4 ]

12 голосов
/ 23 июля 2010

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

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

1 голос
/ 23 июля 2010

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

Iпринять мои тесты, чтобы быть документацией кода.Таким образом, если у меня есть более одного утверждения в утверждении, то есть большая вероятность, что я могу реорганизовать тестируемый метод в несколько более мелких методов или иногда я разделю свой метод теста на несколько различных методов тестирования.Следование правилу «один утверждать на тест» позволяет вам иметь разумные имена методов тестирования, которые, в свою очередь, формируют документацию вашего кода.Соглашение об именах, которое я придерживаюсь для методов тестирования, - methodName_scenario_expectation (из RoyOsherove Art of Unit Testing ).Таким образом, также думает с точки зрения документации кода.Делайте, вы думаете, что утверждение assert (помимо проверки ожидания) поможет вам / другому разработчику лучше понять код, а затем написать это утверждение.Но, повторяя еще раз, всегда проверяйте правильность имен методов тестирования.

0 голосов
/ 23 июля 2010

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

Однако следует проверить, что исключение выбрасывается при передаче недопустимых данныхк этому.

[Test]
public void TestInvalidNameThrowsException {
  MyClass myInstance;
  string namePropertyValue;
  Assert.Throws(() => myInstance = new MyClass(null));
  Assert.Throws(() => myInstance = new MyClass("INVALID_NAME_125356232356"));
}

(например, я не знаю C # один бит. Но вы должны понять.)

0 голосов
/ 23 июля 2010

В вашем конкретном примере вам не нужно утверждать, что что-то не генерируется, если это часть выполнения вашего теста.Этот аспект уже проверен в вашем первом тесте, который более удобочитаем.Если конструктор или свойство get выдают исключение, NUnit не пройдёт тест с соответствующим сообщением об ошибке.TBH Я не уверен, в чем идея Assert.DoesNotThrow (), потому что, если вы его опустите, вы получите почти тот же результат - но определенно не следует использовать его как часть обычного выполнения теста.Весь смысл наличия исключений как части языка состоит в том, что вам не нужно проверять ошибки после каждой отдельной строки кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...