Я просто начинаю с TDD и любопытен относительно того, что приближается, другие берут для запущения их тестов. Для ссылки я использую среду тестирования Google, но я полагаю, что вопрос применим к большинству других сред тестирования и к языкам кроме C/C++.
Мой общий подход до сих пор должен был сделать одну из трех вещей:
Запишите большинству приложения в статической библиотеке, затем создайте два исполняемых файла. Один исполняемый файл является самим приложением, в то время как другой исполнитель тестов со всеми тестами. Обе ссылки на статическую библиотеку.
Встройте код тестирования непосредственно в само приложение, и включите или отключите код тестирования с помощью флагов компилятора. Это - вероятно, лучший подход, который я использовал до сих пор, но загромождает код немного.
Встройте код тестирования непосредственно в само приложение, и, учитывая определенные переключатели командной строки или запустите само приложение или запустите тесты, встроенные в приложение.
Ни одно из этих решений не особенно изящно...
Как дела это?
Я предпочитаю статические библиотеки DLL, поэтому большая часть моего кода на C ++ все равно попадает в статические библиотеки, и, как вы обнаружили, их так же легко тестировать, как и библиотеки DLL.
Для кода, который встраивается в exe, у меня либо есть отдельный тестовый проект, который просто включает исходные файлы, которые тестируются и которые обычно встроены в exe, ИЛИ я создаю новую статическую библиотеку, которая содержит большую часть exe и тестирует это так же, как я тестирую все мои другие статические библиотеки. Я обнаружил, что обычно использую подход «как можно больше кода в библиотеке» с новыми проектами и подход «перетаскивать исходные файлы из проекта exe в тестовый проект», когда я подгоняю тесты к существующим приложениям.
Мне совсем не нравятся ваши варианты 2 и 3. Управлять конфигурациями сборки для 2, вероятно, сложнее, чем иметь отдельный тестовый проект, который просто извлекает нужные ему исходники и включает все тесты в exe, как вы предлагаете в 3, просто неправильно;)
Ваш подход №1 - это то, как я всегда делал это на C / C ++ и Java. Большая часть кода приложения находится в статической библиотеке, и я стараюсь свести количество дополнительного кода, необходимого для приложения, к минимуму.
Мой подход к TDD в Python и других динамических языках немного отличается в том смысле, что я оставляю исходный код для приложения и тестов лежащими без дела, а средство выполнения тестов находит тесты и запускает их.
Я использую два подхода: для dll я просто связываю свои модульные тесты с dll, просто. Для исполняемых файлов я включаю исходные файлы, которые тестируются как в исполняемом проекте, так и в проекте модульного тестирования. Это немного увеличивает время сборки, но означает, что мне не нужно разделять исполняемый файл на статическую библиотеку и основную функцию.
Я использую boost.test для модульного тестирования и cmake для создания файлов проекта, и я считаю, что это самый простой подход. Также я медленно внедряю модульное тестирование в большую базу устаревшего кода, поэтому я стараюсь внести как можно меньше изменений, на случай, если я причиню неудобства другим разработчикам и отговорю их от модульного тестирования. Я бы побеспокоился, что использование статической библиотеки только для модульного тестирования может быть расценено как оправдание не принимать ее.
Сказав это, я думаю, что подход со статической библиотекой хорош, особенно если вы начинаете с нуля.
Я выбираю №1 по некоторым причинам
Для сборки и тестирования C ++ мне нравится использовать CMake, который может запускать выбор целевые исполняемые файлы в качестве тестов и распечатайте сводку результатов.
Для приложений C / C ++ я стараюсь иметь как можно больше кода в одной или нескольких библиотеках DLL, при этом основное приложение является минимальным минимумом для запуска и передачи DLL. Dll намного проще тестировать, потому что они могут экспортировать столько точек входа, сколько мне нужно, для использования в тестовом приложении.
Я использую отдельное тестовое приложение, которое ссылается на Dll. Я решительно за то, чтобы тестовый код и код продукта оставались отдельными модулями.
Я использую сторонние средства запуска тестов с их фреймворком и включаю тестирование в сценарий сборки. Тесты вне производственного кода (внешняя dll).