Только то, что он компилируется, не означает, что он работает! В этом суть модульного тестирования. Попробуйте код из. Убедитесь, что он делает то, о чем вы думали.
Давайте посмотрим правде в глаза: если вы перенесете матричное преобразование из matlab, легко испортить где-нибудь знак плюс или минус. Подобные вещи трудно увидеть. Не пробуя это, вы просто не знаете, будет ли это работать правильно. Отладка 100 строк кода намного проще, чем отладка 100 000 строк кода.
Некоторые люди доводят это до крайности. Они пытаются проверить все мыслимые вещи. Испытание становится самоцелью.
Это может пригодиться позже на этапах обслуживания. Вы можете быстро проверить, что ваши обновления ничего не сломали.
Но накладные расходы могут нанести ущерб разработке продукта! А будущие изменения, которые изменят функциональность, могут повлечь за собой значительные накладные расходы на обновление тестов.
(Это также может привести к путанице в отношении многопоточности и произвольного порядка выполнения.)
В конечном итоге, если не указано иное, мои тесты пытаются достичь среднего уровня.
Я рассчитываю протестировать большие гранулярности, предоставляя средства проверки основных общих функций. Я не очень беспокоюсь о каждом возможном сценарии забора. (Вот для чего нужны макросы ASSERT.)
Например: когда я писал код для отправки / получения сообщений по UDP, я собрал быстрый тест для отправки / получения данных с использованием этого класса через интерфейс обратной связи. Ничего фантастического. Быстрый, быстрый и грязный код. Я просто хотел попробовать это. Чтобы убедиться, что он действительно работал, прежде чем я что-то построил поверх него.
Другой пример: чтение изображений с камеры Firewire. Я собрал быстрое и грязное приложение GTK, чтобы читать изображения, обрабатывать их и отображать в реальном времени. Другие называют это интеграционным тестированием. Но я могу использовать его, чтобы проверить мой интерфейс Firewire, мой класс Image, мое преобразование Bayer RGGB-> RGB, мою ориентацию и выравнивание изображения, даже если камера была снова установлена вверх ногами. Более подробное тестирование было бы оправданным только в том случае, если этого оказалось недостаточно.
С другой стороны, даже для чего-то простого:
template<class TYPE> inline TYPE MIN(const TYPE & x, const TYPE & y) { return x > y ? y : x; }
template<class TYPE> inline TYPE MAX(const TYPE & x, const TYPE & y) { return x < y ? y : x; }
Я написал 1-строчный макрос SHOW, чтобы убедиться, что я не испортил знак:
SHOW(MIN(3,4)); SHOW(MAX(3,4));
Все, что я хотел сделать, это убедиться, что он делает то, что должен делать в общем случае. Я меньше беспокоюсь о том, как он обрабатывает NaN / + -Infinity / (double, int), чем о том, решил ли один из коллег изменить порядок аргументов и обманывают.
С точки зрения инструментов, есть много вещей для юнит-тестирования. Если это поможет вам, больше сил для вас. Если нет, то на самом деле вам не нужно слишком увлекаться.
Я часто пишу тестовую программу, которая выводит данные в класс и из класса, а затем распечатывает все это с помощью макроса SHOW:
#define SHOW(X) std::cout << # X " = " << (X) << std::endl
(В качестве альтернативы, многие из моих классов могут печатать самостоятельно, используя встроенный метод operator << (ostream &). Это удивительно полезный метод для отладки и тестирования!) </p>
Makefiles могут быть тривиально расширены для автоматического создания выходных файлов из тестовых программ и для автоматического сравнения (сравнения) этих выходных файлов с ранее известными (проверенными) результатами.
Не причудливо, возможно, несколько менее элегантно, но с развитием технологий это очень эффективно, быстро реализуется и требует очень мало накладных расходов. (Что имеет свои преимущества, когда ваш менеджер не одобряет тратить время на это тестирование.)
Последняя мысль, которую я оставлю тебе. Это пометит меня, поэтому НЕ сделай это!
Некоторое время назад мне понадобилась программа тестирования. Это был обязательный результат. Сама программа должна была проверить, что другой класс работал правильно. Но он не мог получить доступ к внешним файлам данных. (Мы не могли полагаться на то, где будет располагаться программа относительно чего-либо еще. Абсолютных путей тоже не было.) Среда модульного тестирования для проекта была несовместима с компилятором, который мне нужно было использовать. Это также должно было быть в одном файле. Система makefile проекта не поддерживает связывание нескольких файлов для простой тестовой программы. (Прикладные программы, конечно. Они могут использовать библиотеки. Но только один файл для каждой тестовой программы.)
Так, Боже, прости меня, я "нарушил правила" ...
Я использовал макросы. Когда был установлен макрос #define, данные записывались во второй файл .c в качестве инициализатора для массива struct. Впоследствии, когда программное обеспечение было перекомпилировано, и этот второй файл .c (с массивом struct) был #included и макрос #define не был установлен, он сравнил новые результаты с ранее сохраненными данными. Да, я включил файл .c. О 'смущение всего этого.
Но это можно сделать ...