Тестирование с помощью GTest и GMock: общие и статические библиотеки

Я думаю, что этот вопрос может нарушить некоторые стандарты Q&A для сайта, поскольку ответ(Ы), который я могу получить, можно рассматривать как мнение. Тем не менее, вот оно...

Предположим, мы работаем над проектом 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 делает работу. Я полагаю, некоторые люди сказали бы что-то вроде: "Конечно, сегодня вам не нужна гибкость, но кто знает, что будет завтра?'. Это кажется вопреки моей интуиции, я пытаюсь просмотреть все возможные сценарии, с которыми может столкнуться система, но опять же, есть люди с гораздо большим опытом, чем я.

какие мысли?

2 ответов


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

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

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

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

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


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

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

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