Как организовать модульный тестовый жгут для устаревшего кода Visual C++?


У меня есть проект Visual Studio 2005 C++, это консольное приложение.

Я хочу начать получать биты кода под тестовым жгутом, но я столкнулся с некоторыми проблемами, которые я не знаю, как лучше всего обрабатывать.

Я не хочу, чтобы большая часть моего тестового кода оказалась в норме .exe в производстве, поэтому я подумал, что было бы лучше создать отдельный проект для моих тестов. Во-первых, как этот новый проект будет обращаться к остальной части кода? Должен ли я сделать свой унаследованный код a .Либ или .dll с одной точкой входа и создать отдельный проект, который вызывает основной из моего унаследованного кода?

Должен ли я пойти на уродливый Хак, поместив все мои тесты в файлы, которые полностью #ifdef TESTING, чтобы код не попал в мою продукцию .отлично? Если да, то как я должен условно загрузить свой фреймворк тестирования? Использовать отдельную конфигурацию свойств для тестирования?

Я в основном ищу любые предложения о том, как получить тестовый жгут на наследство .exe проект в Visual C++

2 5

2 ответа:

Во-первых, я настоятельно рекомендую книгу Майкла пера "эффективная работа с устаревшим кодом". Это все о том, как добавить автоматизированные модульные тесты в устаревшее приложение, которое не имеет тестов. Если вы задаетесь вопросом "как мне вообще начать тестировать эту кучу кода", то эта книга для вас.

Майкл также является автором CppUnit, открытого исходного кода NUnit-подобной платформы тестирования для кода C++. Вы можете найти его здесь: http://sourceforge.net/projects/cppunit/.

Один быстрый и простой способ добавить тесты-это добавить в решение конфигурацию UnitTest. Эта конфигурация будет компилировать ваш код, но вместо того, чтобы связывать его с вашим основным.CPP, вы исключаете свою главную.cpp из сборки и включить UnitTestMain.cpp, где вы разместите вызовы для выполнения модульных тестов. Мы начали этот путь давным-давно, когда не знали ничего лучшего. В конечном итоге вы тратите много времени, включая и исключая все различные testMyCode.СРР модулей для различных конфигурации, однако, и это становится утомительным через некоторое время. Мы обнаружили, что разработчикам не слишком нравится такой подход.

Гораздо лучший подход-это добавление проекта модульного тестирования в ваше решение с зависимостью сборки от вашего реального проекта. Если проект называется Foo.vcproj, назовем его Foo_test.vcproj. Этот проект содержит только ваш тестовый код, он #включает ваши заголовки Foo, и он ссылается на ваш скомпилированный fooCode.модули obj. Добавьте вызов для выполнения Foo_test.exe как после построения шаг сборка Foo_test, и она автоматически запускает модульные тесты во время сборки. Если модульные тесты терпят неудачу, построить не удастся. Если на вашем сервере сборки настроены закрытые проверки, никто не сможет проверить изменения, нарушающие существующие тесты.

Я думаю, что иметь большую часть кода, который тестируется, в библиотеке лучше, но не обязательно практично во всех случаях.

Одно из решений состоит в том, чтобы иметь отдельную конфигурацию проекта (например, Debug, Release и Test) и иметь свой тестовый код в отдельных файлах, которые помечены как "исключенные из сборки" в конфигурациях Debug и Release. Вы можете либо иметь простой код для запуска тестов в пределах #ifdef, либо иметь заглушку версии запуска тестов, которая включена в non-Test опирающийся.

Еще один вариант (хотя это довольно Хак-иш) заключается в том, чтобы тестовый код запускался из WinMain, а рабочий код-из обычного старого main. При сборке с использованием подсистемы "Windows" будут выполняться тесты, а при сборке для подсистемы Console - рабочий код. Однако я не знаю, удалит ли компоновщик не вызываемые тестовые функции из производственной сборки.