Как вы проводите свои модульные тесты? Флаги компилятора? Статические библиотеки?

Я только начинаю с 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).