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