У меня есть функция класса (Class member), которую я хочу избежать краха приложения из-за двусмысленности. Для этого я добавил попытку поймать Бок, как показано ниже:попробуйте поймать блоки с boost.Test
void getGene(unsigned int position){
T val;
try {
val = _genome.at(_isCircular ? position % _genome.size() : position);
}
catch (std::exception& e) {
std::cerr << "Error in [" << __PRETTY_FUNCTION__ << "]: "
<< e.what() << std::endl;
exit(1);
}
return val;
}
Теперь я хотел бы добавить модульный тест Boost, который я думал, что делать что-то вроде
BOOST_AUTO_TEST_CASE(nonCircularGenome_test){
// set size to 10
test.setSize(10);
// set non circular
test.setNonCircular();
// gene at site # 12 does not exist in a 10-site long genome, must throw an exception
BOOST_CHECK_THROW(test.getGene(12), std::out_of_range);
Проблема заключается в том, Я не могу заставить обе эти вещи работать. Блок try-catch хорошо работает в настройке релиза. Однако этот тест работает, только если я удаляю блок try-catch и позволяю функции вызывать исключение.
Каков наилучший способ заставить обе эти вещи работать, чтобы пользователь запрашивал правильную ошибку на ходу, а тесты проверяли явно при отладке? Одним из способов является использование # ifdef/# endif блоков DEBUG, но я хочу избежать макросов препроцессора.
Спасибо заранее,
Нихилу
+ 1, но некоторые детали ... вы * можете * иногда проверять неопределенное поведение, это зависит от того, какое неопределенное поведение. В терминах Lakos вы можете тестировать * мягкое * неопределенное поведение (т. Е. Из-за контрактных вызовов в вашу библиотеку), но не * жесткое * неопределенное поведение (т. Е. Что-то, что уже вызвало неопределенное поведение в библиотеке и/или языке). На самом деле есть предложение ([n3604] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3604.pdf)), чтобы добавить некоторую поддержку этому в уровень языка и [BSL] (https://github.com/bloomberg/bsl) имеет реализацию уровня библиотеки. –
@ DavidRodríguez-dribeas: Должен признаться, я слишком давно прочитал это интересное предложение, чтобы точно запомнить его содержание.Теперь я немного озадачен, поэтому я спрошу вас, если вы не возражаете: если нарушение предварительного условия является неопределенным поведением, то вызов этой функции путем нарушения этого предварительного условия приведет к запуску неопределенного поведения, а это означает, что утверждение теста не может ожидать согласованного результата. Неужели я не понимаю этого? Или наш тест должен запускаться в контексте, где обычно неопределенное поведение теперь является четко определенным поведением (например, выбрасыванием исключения)? –
Дело в том, что в вашей функции вы можете проверить предварительные условия * до *, ваша функция сама вызывает неопределенное поведение где-то еще с помощью одного из макросов assert. Структура в Bloomberg/BSL и предложение позволяют конфигурировать то, что происходит, когда утверждение запускается из 'main' (ну, из любой точки кода в любом случае). Теперь в тестовом наборе (вы можете проверить тесты BSL) вы можете настроить обработчик assert как уникальное исключение, и таким образом вы можете добавить тесты, которые подтверждают, что ваш код способен * обнаруживать * UB на вашем собственном интерфейсе [. ..] –