Проверить несколько разных примеров входных данных в одном тесте? - PullRequest
23 голосов
/ 06 мая 2009

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

Тем не менее, я могу придумать несколько разных способов проверить одно и то же функция (test@test.com; test234@test.com; test.test.com и т. д.).

Должен ли я поместить все заклинания, которые мне нужны, в одно и то же тест с несколькими ASSERTS или я пишу новый тест для каждого что я могу придумать?

Спасибо!

Ответы [ 7 ]

10 голосов
/ 06 мая 2009

Большинство платформ тестирования теперь поддерживают своего рода тестирование на основе данных, позволяющее выполнять один и тот же тест для нескольких наборов данных.

См. Атрибут Значения в NUnit.

xUnit.net, MBUnit и другие имеют похожие методы.

8 голосов
/ 09 мая 2009

Обычно я создаю много разных тестов и присваиваю каждому свое имя. Например, предположим, что есть 3 различных регулярных выражения {A, B и C} для сопоставления адреса электронной почты. Функция проверяет входящее электронное письмо на соответствие и принимает первое найденное соответствие.

У меня были бы следующие тесты.

  • ATypeEmailShouldMatchPatternA
  • BTypeEmailShouldMatchPatternB
  • CTypeEmailShouldMatchPatternC
  • BadEmailShouldNotMatchAnyPattern
  • EmailCompatibleWithPatternAAndPatternBShouldBeMatchedByA
  • EmailCompatibleWithPatternAAndCShouldBeMatchedByA
  • EmailCompatibleWithPatternBAndCShouldBeMatchedByB

Как правило, я бы ставил одно утверждение в каждом тесте.

Иногда, однако, я ставлю более одного утверждения в тесте , если все проверки проверяют разные части одной и той же вещи. Например, допустим, у меня есть функция, которая находит все электронные письма, соответствующие шаблону A. Мои тестовые потоки представлены в списке электронных писем, но только один соответствует шаблону A. Функция возвращает список, и я ожидаю, что в этом списке будет только один элемент Это. Так что я бы утверждал две вещи:

  1. То, что в списке есть один элемент.
  2. То, что один элемент - это электронное письмо, которое соответствует шаблону A.
2 голосов
/ 27 мая 2009

Как упомянул @Paul, несколько тестовых сред поддерживают RowTests. Используя эту функцию, вы можете написать нечто чудовищное, как это:

[TestCase ("test@test.com", true)]
[TestCase ("x!x@test.com", true)]
[TestCase ("x#x@test.com", true)]
[TestCase ("x$x@test.com", true)]
[TestCase ("x%x@test.com", true)]
[TestCase ("x&x@test.com", true)]
[TestCase ("x'x@test.com", true)]
[TestCase ("x*x@test.com", true)]
[TestCase ("x+x@test.com", true)]
[TestCase ("x-x@test.com", true)]
[TestCase ("x/x@test.com", true)]
[TestCase ("x=x@test.com", true)]
[TestCase ("x?x@test.com", true)]
[TestCase ("x^x@test.com", true)]
[TestCase ("x_x@test.com", true)]
[TestCase ("x`x@test.com", true)]
[TestCase ("x{x@test.com", true)]
[TestCase ("x{x@test.com", true)]
[TestCase ("x|x@test.com", true)]
[TestCase ("x}x@test.com", true)]
[TestCase ("x~x@test.com", true)]
[TestCase ("test", false)]
[TestCase ("", false)]
[TestCase (null, false)]
public void IsEmail_Should_Match_Valid_Email_Addresses(string target, bool result)
{
    Assert.AreEqual(result, target.IsEmail());
}

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

1 голос
/ 17 апреля 2010

BDD и / или структуры контекста / спецификаций , такие как SubSpec, в которых есть несколько ярких примеров управляют этим, обрабатывая каждый пакет связанных утверждений как отдельный блок наблюдения, которому присваивается имя или описательная метка.

Ключевыми элементами хорошего теста, к которому это подталкивает, являются:

  1. у вас есть разделение AAA / GWT на каждую из фаз - вы вынуждены действительно думать о том, что есть [и часто быстро поймете, когда что-то нужно разбить подробнее]
  2. В результате вы получите хорошие имена / описания в наблюдениях (тесты строк, как правило, оставляют вас с [менее понятными] комментариями в лучшем случае)
  3. При тестах 10 и 17 из 24 [как и в тестах строк] у вас есть статус каждого из тестов, чтобы помочь вам сузить решение

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

Кроме того, PropertyData xUnit.net может быть мощным и подходящим в некоторых случаях для выполнения некоторых трюков в других ответах.

1 голос
/ 06 мая 2009

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

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

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

0 голосов
/ 06 мая 2009

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

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

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

Если ваш тест имеет несколько утверждений, но все еще остается простым (без циклов, без ifs) и , то несколько утверждений проверяют одно и то же, тогда я не был бы таким агрессивным в защиту "единого утверждения за тест". Выбор за вами.

0 голосов
/ 06 мая 2009

Я не думаю, что вам следует писать отдельный тест для каждого случая, поскольку все случаи связаны с одним и тем же, который проверяет, является ли строка правильным адресом электронной почты. Если вы используете MbUnit или NUnit для запуска ваших тестов, то вы можете использовать атрибуты RowTest и Row для передачи различных значений в тест. Другой способ - сохранить все различные форматы электронной почты в массиве, выполнить цикл по массиву и выполнить утверждение.

...