У меня есть куча классов, которые занимаются проверкой значений. Например, RangeValidator
класс проверяет, находится ли значение в указанном диапазоне.
Каждый класс валидатора содержит два метода:, is_valid(value)
который возвращает True
или False
зависит от значения, и ensure_valid(value)
который проверяет указанное значение и либо ничего не делает, если значение является допустимым, либо выдает конкретное исключение, если значение не соответствует предопределенным правилам.
В настоящее время с этим методом связаны два модульных теста:
Тот, который передает недопустимое значение и гарантирует, что было сгенерировано исключение.
def test_outside_range(self): with self.assertRaises(demo.ValidationException): demo.RangeValidator(0, 100).ensure_valid(-5)
Тот, который передает действительное значение.
def test_in_range(self): demo.RangeValidator(0, 100).ensure_valid(25)
Несмотря на то, что второй тест выполняет свою работу - терпит неудачу, если выбрасывается исключение, и успешен, если ensure_valid
ничего не выдает - тот факт, что внутри нет assert
s, выглядит странным. Кто-то, кто читает такой код, сразу же спрашивает себя, почему существует тест, который, похоже , ничего не делает.
Это текущая практика при тестировании методов, которые не возвращают значение и не имеют побочных эффектов? Или я должен переписать тест по-другому? Или просто оставить комментарий, объясняющий, что я делаю?
источник
self
ссылки) и не возвращает результата, она не является чистой функцией.void
во многих языках и имеет глупые правила.) В качестве альтернативы, вы можете иметь бесконечное число цикл (который работает, даже когда «не возвращает результата» действительно означает, что не возвращает результатов.unit -> unit
которая считает единицу стандартным типом данных, а не чем-то магически специальным. К сожалению, он просто возвращает единицу и больше ничего не делает.Ответы:
Большинство тестовых сред имеют явное утверждение «не выбрасывает», например, у Jasmine есть
expect(() => {}).not.toThrow();
и у nUnit, и у друзей есть такое.источник
Это сильно зависит от используемого языка и структуры. Говоря с точки зрения
NUnit
, естьAssert.Throws(...)
методы. Вы можете передать им лямбда-метод:который выполняется в рамках
Assert.Throws
. Вызов лямбда, скорее всего, будет обернутtry { } catch { }
блоком, и утверждение не будет выполнено, если будет обнаружено исключение.Если ваш фреймворк не предоставляет этих средств, вы можете обойти его, обернув вызов самостоятельно (я пишу на C #):
Это делает намерение более ясным, но в некоторой степени загромождает код. (Конечно, вы можете обернуть все эти вещи в метод.) В конце концов, вам решать.
редактировать
Как отметил в комментариях Док Браун, проблема заключается не в том, чтобы указать, что метод выдает, а что он не выдает. В NUnit также есть утверждение
источник
Просто добавьте комментарий, чтобы понять, почему не требуется утверждение и почему вы его не забыли.
Как вы можете видеть из других ответов, все остальное делает код более сложным и загроможденным. С комментариями там другие программисты будут знать цель теста.
При этом, этот вид теста должен быть исключением (не каламбур). Если вы обнаружите, что пишете что-то подобное регулярно, то, вероятно, тесты говорят вам, что дизайн не оптимален.
источник
Вы также можете утверждать, что некоторые методы вызываются (или не вызываются) правильно.
Например:
В вашем тесте:
источник