Связывание в тестовых библиотеках с CppUnit - PullRequest
6 голосов
/ 19 июня 2009

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

runner.addTest( TestClass::suite() );

индивидуально для каждого класса тестов и не может использовать метод makeTests () TestFactoryRegistry для получения списка тестов. Если я просто скомпилирую их все вместе в верхнем каталоге, метод makeTests () будет работать нормально, но я не хочу, чтобы все тестовые классы находились в одном месте, если я могу помочь.

Документация CppUnit дает следующую небольшую подсказку

Проблема с соединением при использовании Helper макросы?

Когда вы создаете проект и пишете его юнит тесты, работа выполнена легче за счет использования так называемые вспомогательные макросы: CPPUNIT_TEST_SUITE_NAMED_REGISTRATION, CPPUNIT_REGISTRY_ADD и CPPUNIT_REGISTRY_ADD_TO_DEFAULT. Проблема в том, что если вы используете те, макросы в файле исходного кода Класс TestFixture (скажем, MyTest как пример), и если вы используете строку вроде этот

runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest()

);

в вашей функции main () в файле main.cpp, там не будет тестового прогона на все!

Причина в том, что ссылка просто этап, один из этапов сборки процесс, не вставляйте объект файлы (файлы .obj или .o) в финале исполняемый, если нет неопределенного символ в вашем main.cpp.

Таким образом, объектный код, который содержит статический регистр авторегистрации инстанцирование переменных не является частью финальный исполняемый файл и не может вставать в бегун функция main ().

Вы должны создать неопределенный символ в main.cpp, чтобы файл mytest.o интегрирован с main.o в окончательный исполняемый файл.

Трюк, совершенный Мишелем Нолардом

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

Теперь я мог бы просто сделать отдельный исполняемый тест для каждой библиотеки, и, в конце концов, я могу пойти по этому пути, но я хотел сначала попытаться заставить это работать, поэтому у меня была только одна программа для тестирования, чтобы проверить все вещь. Любые идеи / примеры того, как заставить это работать?

Ответы [ 3 ]

1 голос
/ 24 июня 2009

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

Например, предполагая две тестовые библиотеки fred и barney, в fredTestLib.cpp вы просто добавили бы эту строку:

int fredDummyInt = 0; // declare a unique symbol for the linker to resolve

и в barneyTestLib.cpp вы добавите похожую строку:

int barneyDummyInt = 0; // a different unique symbol for the linker to resolve

Вы можете скомпилировать каждую библиотеку отдельно за несколько шагов. В основной тестовой программе вы заставляете компоновщик разрешать их. Поэтому добавьте эти строки в main.cpp:

extern int fredDummyInt;
extern int barneyDummyInt;
...
main () {
    ...
    fredDummyInt++; // give the linker some symbols to resolve
    barneyDummyInt++;
    ...

Идея (в соответствии с тем, что говорит автор вышеприведенного трюка) состоит в том, что поскольку компоновщик уже ищет fredTest.lib для fredDummyInt, он также найдет и разрешит ваши автоматически зарегистрированные тесты.

Примечание: я не пробовал это проверить, работает ли он! Я просто отвечаю на ваш вопрос о внешнем.

Другим подходом, который следует рассмотреть, будет создание ваших тестов в DLL и использование LoadLibrary () для явного запуска их в работу. Для избыточного использования, если вы используете MfcUi :: TestRunner, вы, вероятно, могли бы создать небольшой выпадающий графический интерфейс, который позволит вам выбрать библиотеку для загрузки, загрузить ее, затем отобразить тесты для запуска в этой библиотеке и запустить их.

0 голосов
/ 16 января 2013

Я понимаю, что этот пост сейчас довольно старый, но для всех, кто сталкивается с ним: Один из способов решить эту проблему, не имея ссылок в вашем коде, - дать указание (заставить) компоновщику включить всю двоичную статическую библиотеку. Подробная информация доступна на страницах справочника gcc & ld, и этот пост также освещает это: Как заставить gcc связать статические объекты C ++, на которые нет ссылок, из библиотеки

Для справочной страницы ld важно рассмотреть возможность явного отключения этой опции (также показано в одном из примеров выше).

0 голосов
/ 25 января 2012

Решение этой проблемы довольно простое, как и раньше (но может быть не очень элегантным). Для каждой TestFixture, которая находится во внешней библиотеке, вы должны добавить следующие две строки кода в основной модуль

#include <CppUnitTestFixtureExample.h>
CppUnitTestFixtureExample Test1;

Создает неиспользуемую фиктивную переменную, которая не используется, она просто заставляет компоновщик связать тестовое устройство. Теперь исполнитель теста, расположенный в главном модуле, может выполнить тест.

...