Наш проект использует Boost.Test для наших юнит-тестов. Мы хотели бы получать мини-дампы, когда неожиданные исключения возникают и во время наших тестовых случаев, поэтому мы начали интегрировать Google Breakpad для написания мини-дампов.
Похоже, что Boost.Test перехватывает все выданные исключения из пользовательских тестов — я предполагаю, потому что тестовые примеры Boost обертывают каждую функцию try / catch и модульный тест просто не проходит, если выдается непредвиденное исключение. Это не позволяет обработчику исключений Breakpad запускать и записывать мини-дампы.
Возможно ли, чтобы Boost.Test не просто ловил и терпел неудачу при неожиданных исключениях в модульных тестах? И вместо этого позволить исключениям остаться необработанными (или перебросить), чтобы можно было запустить Breakpad или другой обработчик исключений, чтобы написать мини-дамп?
Boost.Test предназначен для перехвата всех исключений из тестового примера, чтобы продолжить выполнение других тестовых случаев. Я не думаю, что вы можете отключить это поведение, но вы всегда можете обратиться к исходному коду.
Чтобы добиться того, что вам нужно, я бы сам обернул тело тестовых случаев и поймал исключения, а при возникновении неожиданных исключений выписывал мини-дампы. Вы можете обобщить это, написав обработчик catch / dump как функцию, которая принимает функтор, являющийся вашим телом тестового примера, и вызывает ваш обработчик с телом тестового случая в лямбда-выражении:
void handler(std::function<void()> test_case)
{
try {
test_case();
} catch (...) {
write_minidump();
}
}
BOOST_AUTO_TEST_CASE(doit)
{
handler([] {
// do testing here
});
}
Это будет более сложным, если вы используете приборы, но применима та же идея.
Я пробовал несколько разных подходов, но следующее решение дает лучший результат. Определение макроса для переноса макроса BOOST_AUTO_TEST_CASE и окружение вызывающего кода SEH __try / __ кроме и передача данных об исключениях в Breakpad.
#define CUSTOM_AUTO_TEST_CASE( test_name ) \
void test_name##_custom_wrapper(); \
\
BOOST_AUTO_TEST_CASE( test_name ) \
{ \
__try \
{ \
test_name##_custom_wrapper(); \
} \
__except(pHandler->WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {} \
} \
\
void test_name##_custom_wrapper() \
Где pHandler — указатель Breakpad ExceptionHandler.
Недостатком является то, что вы должны заменять каждое вхождение BOOST_AUTO_TEST_CAST макросом-оболочкой. Но это делает трюк.