2014-01-20 3 views
6

Я думаю, что этот вопрос может нарушить некоторые из Q & Стандарты для сайта, так как ответы, которые я могу получить, могут рассматриваться как ориентированные на мнение. Тем не менее, здесь идет ...Тестирование с помощью GTest и GMock: общие или статические библиотеки

Предположим, что мы работаем над проектом C++, используя CMake для управления процессом сборки/тестирования/упаковки, а также GTest и GMock для тестирования. Далее предположим, что структура нашего проекта выглядит следующим образом:

cool_project 
| 
|-- source 
| | 
| |-- module_foo 
| | | 
| | |-- (bunch of source files) 
| | 
| |-- module_bar 
| | 
| |-- (yet more source files) 
| 
|-- tests 
| 
|-- module_foo 
| | 
| |-- (tests for module_foo) 
| 
|-- module_bar 
| 
|-- (tests for module_bar) 

Это, конечно, упрощенное положение, но вы получите идею.

Теперь хорошо, если эти модули являются библиотеками и каждым тестом (т. Е. Каждый каталог под tests) является исполняемым, мы должны связать его с первым. Дело в том, что если эти библиотеки разделены, загрузчик, конечно же, должен их найти. Очевидным решением является установка рабочего каталога теста в каталог библиотеки, используя CMake's set_property. Однако, если и GTest, и GMock также были созданы как разделяемые библиотеки, это не сработает, поскольку они также должны быть загружены.

Решения я придумал были:

  • Скопируйте обе библиотеки (т.е. GTEST и GMock) в каталог сборки модуля. Это кажется глупым, поскольку основное преимущество разделяемых библиотек (т. Е. Совместного использования кода между программами) полностью исключается, и мы получаем несколько копий этих файлов по всему каталогу.
  • Создайте как GTest, так и GMock вместо статических библиотек. Это означает, что теперь мы получаем копию обеих библиотек в каждый исполняемый файл, что увеличивает его размер. Несмотря на то, что у нас нет 1000 тестов, это чувствует себя как-то неловко.

Итак, учитывая эту ситуацию, я хотел бы знать, был ли кто-либо когда-либо с ним связан, и какой путь он или она взял. (Если бы решение было отличным от тех, о которых я упоминал, я был бы рад услышать все об этом.) В идеале я хотел бы быть в положении, в котором мог бы make && make test и провести все тесты, без необходимости запускать любой дополнительный скрипт для размещения вещей. Наличие всех библиотек, построенных как статические библиотеки, выполняет эту работу, но что, если я создаю их как общие библиотеки? Должен ли я строить их дважды? Это глупо.

Другая проблема также протекает вдоль этих линий, но я думаю, что ее решение включает в себя редизайн или аналогичный артефакт. Предположим, что module_foo зависит от сторонней библиотеки, например. library_baz. Если module_foo ссылки непосредственно на library_baz, то любой тест на первом нужно будет загрузить library_baz, хотя он может тестировать несвязанные функции. Такая же проблема возникает.

Отказывание похоже на правильную вещь здесь, но как-то я чувствую, что не имеет смысла рефакторинг module_foo, чтобы он мог разговаривать с интерфейсом (будь то в силу динамического или статического полиморфизма), поскольку ему не нужна такая гибкость: library_baz выполняет эту работу. Я полагаю, что некоторые люди скажут что-то вроде «Конечно, сегодня вам не нужна гибкость, но кто знает завтра?». Это кажется мне интригующим, пытаясь просмотреть все возможные сценарии, с которыми может столкнуться система, но опять же, есть люди с гораздо большим опытом, чем я.

Любые мысли?

+0

Вы считаете установку 'gtest' и' gmock' в качестве локальных общих библиотек в системе, то есть в '/ usr/local/lib'? Динамическая связь найдет их там, если ваши пути поиска ldconfig нормальны, а затем вы можете просто добавить '-lgtest -lgmock -pthread' в параметры привязки ваших тестов. Есть ли какая-то причина, которая не будет работать для вашей тестовой установки? –

+0

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

ответ

2

Кажется, я пытался убить комара с помощью ядерной ракеты.

Решение, с которым я столкнулся, состояло в том, чтобы просто собрать все библиотеки в качестве статических объектов при тестировании. Правда, в итоге у меня довольно большие двоичные файлы, но я не буду распространять их.

Итак, подведем итоги:

  • Оба GTEST и GMock построены как статические библиотеки.
  • То же самое касается библиотек, которые содержат функциональность, которую я тестирую.
  • Тестирование тогда связывается с ними и, таким образом, может запускаться без каких-либо проблем с рабочим каталогом.

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

0

Таким образом, я вижу это делается (по крайней мере, на Windows, я не развиваюсь на * NIX) совершенно не зависит от любого тестирования:

Просто всех бинарных сборки артефактов и зависимости, которые необходимы для запуска должны быть скопированы (или созданы непосредственно) в каталог ./bin.

Затем вы можете выполнить любой исполняемый файл из этого каталога ./bin, и все доступные библиотеки находятся там.

+0

Имеет смысл, но я думаю, что создание проекта с включенным тестированием и последующим вашим советом будет производить _a большое количество двоичных файлов в каталоге 'bin', так как я использую CTest, и каждый тест в основном является исполняемым. В любом случае, спасибо за ваш ответ. –

+0

@faranwath - Обратите внимание, что я * * не * предлагаю любой глобальный каталог '/ bin'. Просто '..../my_project_dir/bin'. Этого должно быть достаточно, не так ли? –

+0

Абсолютно, я просто хотел посмотреть, знает ли кто-нибудь, как это делать, но моя надежда была основана исключительно на личных и не практических вопросах. Как я уже сказал, ваш ответ квалифицируется как полезный. –

Смежные вопросы