Проектирование по контракту и модульное тестирование в Stack Overflow

Я пытаюсь объединить базовый дизайн по контракту (реализованный макросами, использующими встроенную функцию assert) и модульное тестирование Google Test в приложении.

Так, например, у меня есть следующий код:

AppFavorite* AppFavorites::Add(const UnicodeString& link)
{
REQUIRE(!link.IsEmpty());

...
}

Теперь у меня не может быть следующего теста в моих модульных тестах, потому что IDE прерывается при достижении assert (REQUIRE (! Link.IsEmpty ());):

TEST(AppFavoritesTest, AddEmpty)
{
AppFavorites favorites;
ASSERT_THROW(favorites.Add(L""), std::invalid_argument);
}

Итак, мой вопрос, должен ли я либо:

  1. Никогда не проверяйте условия, предусмотренные контрактами, или
  2. Отключить как-то проверку контракта во время юнит-тестов?

2

Решение

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

Похоже, ваше намерение состоит в том, чтобы поведение было неопределенным, то есть контракт ничего не говорит о том, что произойдет, если будет передана пустая строка. В этом случае самый простой способ проверить правильность вашего контракта — это создать свои юнит-тесты для негативного тестирования в виде специальной сборки с REQUIRE изменено, чтобы выдать какое-то исключение «нарушено предусловие», которое вы затем проверили бы с помощью ASSERT_THROW

Я настоятельно рекомендую смотреть Доклад Джона Лакоса о защитном программировании от ACCU 2011, это охватывает именно эту проблему

5

Другие решения

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

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

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

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

1

По вопросам рекламы [email protected]