Тестирование с помощью 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 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 делает свою работу. Я полагаю, что некоторые люди сказали бы что-то вроде «Конечно, вам не нужна гибкость сегодня, но кто знает завтра?». Мне кажется нелогичным пытаться предварительно просмотреть все возможные сценарии, с которыми может столкнуться система, но опять же, есть люди с гораздо большим опытом, чем я.

есть идеи?


person Community    schedule 20.01.2014    source источник
comment
Рассматриваете ли вы возможность установки gtest и gmock в качестве локальных общих библиотек в системе, то есть в /usr/local/lib? Динамическое связывание найдет их там, если ваши ldconfig пути поиска нормальные, а затем вы можете просто добавить -lgtest -lgmock -pthread к параметрам связывания ваших тестов. Есть ли какая-то причина, по которой ваша тестовая установка не работает?   -  person Mike Kinghan    schedule 21.01.2014
comment
Прежде всего, извините за (очень) поздний ответ. Причина, по которой эта установка не будет идеальным решением этой проблемы, заключается в том, что в идеале я хотел бы развернуть тесты вместе с приложением, и я не хочу заставлять пользователей устанавливать вещи, о которых некоторые из них могут не знать. .   -  person    schedule 03.02.2014


Ответы (2)


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

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

Итак, резюмируя:

  • И GTest, и GMock построены как статические библиотеки.
  • То же самое касается библиотек, содержащих те функции, которые я тестирую.
  • Затем тесты связываются с ними, и поэтому их можно запускать, вообще не вмешиваясь в рабочий каталог.

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

person Community    schedule 12.03.2014

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

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

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

person Martin Ba    schedule 12.02.2014
comment
Это имеет смысл, но я думаю, что создание проекта с включенным тестированием и следование вашим советам приведет к созданию большого количества двоичных файлов в каталоге bin, поскольку я использую CTest, и каждый тест в основном представляет собой исполняемый файл. В любом случае спасибо за ваш ответ. - person ; 13.02.2014
comment
@faranwath. Обратите внимание, что я не предлагаю какой-либо глобальный каталог /bin. Просто ..../my_project_dir/bin. Этого должно быть достаточно, не так ли? - person Martin Ba; 13.02.2014
comment
Безусловно, я просто хотел посмотреть, знает ли кто-нибудь, как избежать этого, но моя надежда была основана исключительно на личных, а не на практических вопросах. Как я уже сказал, ваш ответ действительно считается полезным. - person ; 13.02.2014
comment
@faranwath - В чем проблема иметь много тестовых исполняемых файлов в одном каталоге? - person Martin Ba; 13.02.2014
comment
Я не совсем понимаю, почему мы продолжаем обсуждать это, но вот оно: с этим нет абсолютно никаких проблем, и на самом деле это может быть решение, которое я выберу в будущем. Я просто хотел поместить каждый тестовый исполняемый файл в каталог, связанный с тестируемым модулем. Учитывая, что я организую их в соответствии со структурой модулей, часть моего мозга, любящая симметрию, подумала, что это отличная идея. - person ; 13.02.2014