Тестирование с помощью 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
каталог и все общие библиотеки находятся на месте.