Недавно мне предложили использовать CMake для компиляции моих проектов на C ++, и теперь я хотел бы начать писать несколько модульных тестов для своего кода. Я решил использовать утилиту Google Test, чтобы помочь с этим, но мне нужна помощь для начала работы.
Весь день я читал различные руководства и примеры, включая Primer , введение в IBM и некоторые вопросы по SO ( здесь и здесь ), а также другие источники, которые я потерял. Я понимаю, что есть много чего, но почему-то все еще испытываю трудности.
В настоящее время я пытаюсь реализовать самый простой тест, чтобы убедиться, что я правильно скомпилировал / установил gtest, и он не работает. Только исходный файл (testgtest.cpp) берется почти точно от этого предыдущего ответа:
#include <iostream>
#include "gtest/gtest.h"
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
и мой связанный CMakeLists.txt выглядит следующим образом:
cmake_minimum_required(VERSION 2.6)
project(basic_test)
# Setup testing
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIR})
# Add test cpp file
add_executable(runUnitTests
testgtest.cpp
)
# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests ${GTEST_LIBRARY_DEBUG} ${GTEST_MAIN_LIBRARY_DEBUG})
add_test(
NAME runUnitTests
COMMAND runUnitTests
)
Обратите внимание, что я решил связать с gtest_main вместо предоставления main в конце файла cpp, поскольку я считаю, что это позволит мне легче масштабировать тестирование до нескольких файлов.
При создании сгенерированного файла .sln (в Visual C ++ 2010 Express) я, к сожалению, получаю длинный список ошибок в форме
2>msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: virtual __thiscall std::basic_iostream<char,struct std::char_traits<char> >::~basic_iostream<char,struct std::char_traits<char> >(void)" (??1?$basic_iostream@DU?$char_traits@D@std@@@std@@UAE@XZ) already defined in gtestd.lib(gtest-all.obj)
что, я думаю, означает, что я не могу успешно подключиться к библиотекам gtest. Я убедился, что при компоновке с библиотеками отладки я попытался создать в режиме отладки.
РЕДАКТИРОВАТЬ
Покопавшись еще раз, я думаю, что моя проблема связана с типом библиотеки, в которую я встраиваю gtest. При создании gtest с помощью CMake, если этот BUILD_SHARED_LIBS
флажок не установлен, и я связываю свою программу с этими файлами .lib, я получаю упомянутые выше ошибки. Однако, если этот BUILD_SHARED_LIBS
флажок установлен, я создаю набор файлов .lib и .dll. При связывании этих файлов .lib программа компилируется, но при запуске жалуется, что не может найти gtest.dll.
В чем разница между библиотекой a SHARED
и not SHARED
, и если я выберу вариант not shared, почему она не работает? Есть ли вариант в CMakeLists.txt для моего проекта, который мне не хватает?
ExternalProject_Add
вместоadd_subdirectory
. См. Этот ответ для подробностей.enable_testing()
делать?Ответы:
Решение заключалось в том, чтобы поместить исходный каталог gtest в подкаталог вашего проекта. Я включил рабочий файл CMakeLists.txt ниже, если он кому-то поможет.
источник
pthread
в связанные библиотеки, изменив вторую последнюю строку наtarget_link_libraries(runUnitTests gtest gtest_main pthread)
make test
тесты или запустить ихctest
из каталога сборки. Запустите,ctest -V
чтобы увидеть как результат теста Google, так иctest
результат.Вот полный рабочий пример, который я только что протестировал. Он загружается непосредственно из Интернета, либо фиксированный архив, либо каталог последней версии Subversion.
источник
https://github.com/google/googletest/archive/release-1.8.0.zip
GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1
вместо URLhttps://github.com/google/googletest/archive/release-1.10.0.zip
Вы можете получить лучшее из обоих миров. Можно использовать
ExternalProject
для загрузки исходного кода gtest, а затем использовать егоadd_subdirectory()
для добавления в свою сборку. Это дает следующие преимущества:При обычном использовании ExternalProject не будет выполнять загрузку и распаковку во время настройки (то есть при запуске CMake), но вы можете заставить его делать это, приложив немного усилий. Я написал сообщение в блоге о том, как это сделать, которое также включает обобщенную реализацию, которая работает для любого внешнего проекта, использующего CMake в качестве своей системы сборки, а не только gtest. Вы можете найти их здесь:
Обновление: этот подход теперь также является частью документации googletest .
источник
Скорее всего, в таких ошибках виновата разница в параметрах компилятора между вашим тестовым двоичным файлом и библиотекой Google Test. Вот почему рекомендуется использовать Google Test в исходной форме и создавать его вместе с вашими тестами. В CMake это сделать очень просто. Вы просто вызываете
ADD_SUBDIRECTORY
путь к корневому каталогу gtest, а затем можете использовать определенные там цели публичной библиотеки (gtest
иgtest_main
). Дополнительная справочная информация содержится в этой ветке CMake в группе googletestframework.[править] На данный момент эта
BUILD_SHARED_LIBS
опция действует только в Windows. Он определяет тип библиотек, которые вы хотите создать в CMake. Если вы установите егоON
, CMake будет строить их как библиотеки DLL, а не как статические библиотеки. В этом случае вам нужно создать свои тесты с -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 и скопировать файлы DLL, созданные CMake, в каталог с вашим тестовым двоичным кодом (CMake по умолчанию помещает их в отдельный выходной каталог). Если gtest в статической библиотеке не работает для вас, проще не устанавливать эту опцию.источник
Это потому, что вам нужно добавить -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 в определения компилятора в вашем проекте, если вы хотите использовать gtest в качестве разделяемой библиотеки.
Вы также можете использовать статические библиотеки, если вы скомпилировали их с опцией gtest_force_shared_crt, чтобы устранить ошибки, которые вы видели.
Библиотека мне нравится, но добавить ее в проект - настоящая боль. И у вас нет шансов сделать это правильно, если вы не копаетесь (и не взламываете) в файлах gtest cmake. Позор. В частности, мне не нравится идея добавления gtest в качестве источника. :)
источник
OP использует Windows, и сегодня гораздо более простой способ использовать GTest - это vcpkg + cmake.
Установите vcpkg в соответствии с https://github.com/microsoft/vcpkg и убедитесь, что вы можете запускаться
vcpkg
из строки cmd. Обратите внимание на папку установки vcpkg, например.C:\bin\programs\vcpkg
,Установите gtest с помощью
vcpkg install gtest
: это загрузит, скомпилирует и установит GTest.Используйте CmakeLists.txt, как показано ниже: обратите внимание, что мы можем использовать цели вместо включения папок.
Запустите cmake с помощью: (при необходимости отредактируйте папку vcpkg и убедитесь, что путь к файлу цепочки инструментов vcpkg.cmake правильный)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:\bin\programs\vcpkg\scripts\buildsystems\vcpkg.cmake
и строить
cmake --build build
как обычно. Обратите внимание, что vcpkg также скопирует необходимый файл gtest (d) .dll / gtest (d) _main.dll из папки установки в папки Debug / Release.Протестируйте с помощью
cd build & ctest
.источник
Ваши решения и решения Влада Лосева, наверное, лучше моих. Однако, если вам нужно решение методом перебора, попробуйте следующее:
источник
Самый простой файл CMakeLists.txt, который я извлек из ответов в этой ветке, а также методом проб и ошибок:
Gtest уже должен быть установлен в вашей системе.
источник
Так же, как обновление комментария @ Patricia в принятом ответе и комментария @ Fraser к исходному вопросу, если у вас есть доступ к CMake 3.11+, вы можете использовать функцию CMake FetchContent .
На странице CMake FetchContent в качестве примера используется googletest!
Я сделал небольшую модификацию принятого ответа:
Вы можете использовать
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
свойство target для целей gtest и gtest_main, поскольку они установлены в скрипте CMakeLists.txt Google test .источник
target_include_directories
и использоватьFetchContent_MakeAvailable(googletest)
вместо него. Это одновременно заполнит контент и добавит его в основную сборку. CMake FetchContent - подробнееЯ решил быстро собрать что-то общее, демонстрируя способ, отличный от ранее опубликованных, в надежде, что это может кому-то помочь. Следующее сработало для меня на моем Mac. Сначала я запустил команды настройки для gtests. Я просто использовал найденный сценарий, чтобы все настроить.
Затем я сделал простую структуру папок и написал несколько быстрых классов
Я сделал CMakeLists.txt верхнего уровня для папки utils и CMakeLists.txt для папки тестов.
Это CMakeLists.txt в папке с тестами.
Тогда все, что осталось, это написать образец gtest и gtest main
образец gtest
образец gtest main
Затем я могу скомпилировать и запустить gtests с помощью следующих команд из папки utils
источник