Юнит тестирование конкретных значений - PullRequest
3 голосов
/ 15 августа 2010

Рассмотрим следующий код (из требования, в котором говорится, что 3 является особенным по какой-то причине):

bool IsSpecial(int value)
   if (value == 3)
      return true
   else
      return false

Я бы протестировал это с помощью пары функций - одна с именем TEST (3IsSpecial), которая утверждаетчто при пропуске 3 функция возвращает истину, а другая передает некое случайное значение, отличное от 3, и утверждает, что функция возвращает ложь.

Когда требование меняется и говорят, что теперь оно становится 3, а 20 являются специальными, я бы написалдругой тест, который проверяет, что при вызове с 20 эта функция также возвращает true.Этот тест провалился бы, и я затем пошел бы и обновил условие if в функции.

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

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

Ответы [ 4 ]

2 голосов
/ 15 августа 2010

Хороший вопрос.Как вы заметили, Not3IsNotSpecial тест, выбирающий случайное значение, отличное от 3, будет традиционным подходом.Это не приведет к изменению определения «special».

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

Contract.Ensures(value != 3 && Contract.Result<Boolean>() == false);

Я думаю, что любой, кто является поклонником TDD, сейчас экспериментирует с контрактами, чтобы увидеть образцы использования.Идея, что у вас есть инструменты для доказательства правильности, очень мощная.Вы можете даже указать эти предикаты для интерфейса.

Единственный подход к тестированию, который я видел, который бы разрешил это, - Тестирование на основе моделей .Идея похожа на контрактный подход.Вы устанавливаете условие Not3IsNotSpecial абстрактно (например, IsSpecial(x => x != 3) == false)) и позволяете среде выполнения модели генерировать конкретные тесты.Я не уверен, но я думаю, что эти среды также проводят статический анализ.В любом случае, вы позволяете среде исполнения модели постоянно работать против вашей SUT.Я никогда не использовал такую ​​среду, но концепция интересна.

1 голос
/ 15 августа 2010

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

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

Таким образом, ваш метод станет:

bool IsSpecial(int value)
   if (SpecialValues.has(value))
      return true
   else
      return false

, и ваши значения SpecialValues ​​будут выглядеть как:

enum SpecialValues {

Три (3), Двадцать (20)

   public int value;
}

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

1 голос
/ 15 августа 2010

К сожалению, этот конкретный сценарий трудно предотвратить. С такой функцией, как IsSpecial, нереально протестировать все четыре миллиарда отрицательных тестовых случаев, поэтому нет, вы не делаете что-то в корне неправильно.

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

Мне никогда не приходилось настраивать одну из этих систем, поэтому я не знаю, что с этим связано, но я знаю, что это возможно.

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

0 голосов
/ 15 августа 2010

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

  • 20 могло бы быть некоторым допустимым условием для проверки на основе знаний о предметной области бизнеса.Написание тестов в стиле BDD, основанное на знании бизнес-проблемы, возможно, помогло бы вам явно ее уловить.

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

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