Есть два вида ошибок, которые я хотел бы проверить: инварианты и ошибки времени выполнения.
Инварианты - это вещи, которые всегда должны быть правдой, несмотря ни на что. Для них я использую утверждения. Такие вещи, как вы не должны передавать мне нулевой указатель для буфера вывода, который вы мне даете. Это ошибка в коде, простая и понятная. В отладочной сборке он подтвердит и даст мне возможность исправить это. В розничной сборке это вызовет нарушение прав доступа и создаст мини-дамп (Windows, по крайней мере, в моем коде) или coredump (Mac / unix). catch
, который я могу сделать, не имеет смысла иметь дело с разыменованием нулевого указателя. В Windows catch (...)
может подавлять нарушения прав доступа и давать пользователю ложное чувство уверенности в том, что все в порядке, когда они уже пошли ужасно, ужасно неправильно.
Это одна из причин, почему я пришел к выводу, что catch (...)
- это, как правило, запах кода в C ++, и единственное разумное место, где я могу думать о том, что присутствие присутствует, - main
(или WinMain
) правильно прежде чем вы создадите дамп ядра и вежливо выйдите из приложения.
Ошибки во время выполнения - это такие вещи, как «Я не могу записать этот файл из-за разрешений» или «Я не могу записать этот файл, потому что диск заполнен». Для такого рода ошибок выбрасывать исключение имеет смысл, поскольку пользователь может что-то с этим сделать, например, изменить разрешение на каталог, удалить некоторые файлы или выбрать другое место для сохранения файла. Эти ошибки времени выполнения исправимы пользователем. Нарушение инварианта не может быть исправлено пользователем, только программистом. (Иногда они совпадают, но обычно это не так.)
Ваши модульные тесты должны заставить код выдавать исключения ошибок времени выполнения, которые может генерировать ваш код. Возможно, вы также захотите вызвать исключения от ваших соавторов, чтобы гарантировать, что ваша тестируемая система безопасна для исключений.
Однако я не верю, что имеет смысл пытаться заставить ваш код защищаться от инвариантов с помощью модульных тестов.