Jak rozpocząć pracę z GTest i CMake
Ostatnio sprzedano mi CMake do kompilacji moich projektów C++, a teraz chciałbym zacząć pisać kilka testów jednostkowych dla mojego kodu. Zdecydowałem się skorzystać z narzędzia Google Test, aby w tym pomóc, ale potrzebuję pomocy w rozpoczęciu.
Cały dzień czytałem różne Poradniki i przykłady obejmują Primer , wprowadzenie W IBM i kilka pytań na temat SO ( tutaj i tutaj), a także inne źródła, które straciłem. I zdaję sobie sprawę, że jest ich dużo, ale jakoś wciąż mam problemy.
Obecnie próbuję zaimplementować najbardziej podstawowy test, aby potwierdzić, że dobrze skompilowałem / zainstalowałem gtest i nie działa. Jedyny plik źródłowy (testgtest.cpp) pochodzi niemal dokładnie z tej poprzedniej odpowiedzi:
#include <iostream>
#include "gtest/gtest.h"
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
I moich powiązanych Cmakelistów.txt jest następujący:
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
)
Zauważ, że wybrałem link do gtest_main zamiast podawać main na końcu cpp plik, ponieważ wierzę, że pozwoli mi to łatwiej skalować testowanie do wielu plików.
Podczas budowania wygenerowanego .plik sln (w Visual C++ 2010 Express) niestety dostaję długą listę błędów formularza
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)
Co chyba oznacza, że nie linkuję z bibliotekami gtest. Upewniłem się, że podczas łączenia z bibliotekami debugowania próbowałem budować w trybie debugowania.
EDIT
Po dokładnym pokopaniu, ja myślę, że mój problem ma coś wspólnego z typem biblioteki, w której buduję gtest. Podczas budowania gtest z CMake, jeśli BUILD_SHARED_LIBS
jest nie zaznaczone, a ja łączę mój program z nimi .pliki lib dostaję błędy wymienione powyżej. Jeśli jednak BUILD_SHARED_LIBS
jest zaznaczone, to generuję zbiór .lib i .pliki dll. Kiedy teraz łączy się z nimi .pliki lib program kompiluje, ale po uruchomieniu skarży się, że nie może znaleźć gtest.dll.
Jakie są różnice między SHARED
a nie SHARED
biblioteką, a jeśli wybierz opcję Nie udostępniane, dlaczego to nie działa? Czy istnieje opcja w Cmakelistach.txt dla mojego projektu, którego mi brakuje?
7 answers
Rozwiązanie polegało na umieszczeniu katalogu źródłowego gtest jako podkatalogu twojego projektu. Włączyłem działające Cmakelisty.txt poniżej, jeśli jest to pomocne dla kogokolwiek.
cmake_minimum_required(VERSION 2.6)
project(basic_test)
################################
# GTest
################################
ADD_SUBDIRECTORY (gtest-1.6.0)
enable_testing()
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
################################
# Unit Tests
################################
# Add test cpp file
add_executable( runUnitTests testgtest.cpp )
# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests gtest gtest_main)
add_test( runUnitTests runUnitTests )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-31 11:29:03
Oto kompletny działający przykład, który właśnie przetestowałem. Pobiera bezpośrednio z sieci, albo stały tarball, albo najnowszy katalog subversion.
cmake_minimum_required (VERSION 3.1)
project (registerer)
##################################
# Download and install GoogleTest
include(ExternalProject)
ExternalProject_Add(gtest
URL https://googletest.googlecode.com/files/gtest-1.7.0.zip
# Comment above line, and uncomment line below to use subversion.
# SVN_REPOSITORY http://googletest.googlecode.com/svn/trunk/
# Uncomment line below to freeze a revision (here the one for 1.7.0)
# SVN_REVISION -r700
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(gtest source_dir binary_dir)
################
# Define a test
add_executable(registerer_test registerer_test.cc)
######################################
# Configure the test to use GoogleTest
#
# If used often, could be made a macro.
add_dependencies(registerer_test gtest)
include_directories(${source_dir}/include)
target_link_libraries(registerer_test ${binary_dir}/libgtest.a)
target_link_libraries(registerer_test ${binary_dir}/libgtest_main.a)
##################################
# Just make the test runnable with
# $ make test
enable_testing()
add_test(NAME registerer_test
COMMAND registerer_test)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-26 23:25:16
Najprawdopodobniej za takie błędy winna jest różnica w opcjach kompilatora pomiędzy Twoim testowym binarnym a biblioteką Google Test. Dlatego zaleca się wprowadzenie Google Test w formie źródłowej i zbudowanie go wraz z testami. Jest to bardzo łatwe do zrobienia w CMake. Po prostu wywołujesz ADD_SUBDIRECTORY
ze ścieżką do katalogu głównego gtest i możesz użyć tam zdefiniowanych celów Biblioteki Publicznej (gtest
i gtest_main
). Więcej informacji znajdziesz w tym wątku CMake w googletestframework group.
[edytuj]
Opcja BUILD_SHARED_LIBS
jest na razie skuteczna tylko w systemie Windows. Określa typ bibliotek, które CMake ma zbudować. Jeśli ustawisz ją na ON
, CMake zbuduje je jako biblioteki DLL w przeciwieństwie do bibliotek statycznych. W takim przypadku musisz zbudować swoje testy za pomocą-DGTEST_LINKED_AS_SHARED_LIBRARY=1 i skopiować pliki DLL wytworzone przez CMake do katalogu z binarnym testem (CMake domyślnie umieszcza je w oddzielnym katalogu wyjściowym). Chyba że gtest w static lib nie działa dla Ciebie, łatwiej nie ustawić tej opcji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-16 16:42:33
Możesz dostać to, co najlepsze z obu światów. Możliwe jest użycie ExternalProject
, aby pobrać źródło gtest, a następnie użyć add_subdirectory()
, aby dodać je do swojej kompilacji. Ma to następujące zalety:
- gtest jest zbudowany jako część twojej głównej kompilacji, więc używa tych samych flag kompilatora itp. a tym samym unika problemów takich jak te opisane w pytaniu.
- nie ma potrzeby dodawania źródeł gtest do własnego drzewa źródeł.
Używany w normalny sposób, ExternalProject nie zrobi Pobierz i rozpakuj w czasie konfiguracji (np. gdy CMake jest uruchomiony), ale możesz to zrobić przy odrobinie pracy. Napisałem post na blogu o tym, jak to zrobić, który zawiera również ogólną implementację, która działa dla każdego zewnętrznego projektu, który używa CMake jako swojego systemu budowania, a nie tylko gtest. Można je znaleźć tutaj:
Aktualizacja: to podejście jest teraz również częścią dokumentacji googletest .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 09:44:07
Po dokładniejszym pokopaniu, myślę, że mój problem ma coś wspólnego z typem biblioteki, w której buduję gtest. Podczas budowania gtest z CMake, jeśli BUILD_SHARED_LIBS nie jest zaznaczony, a ja łączę mój program z nimi .pliki lib dostaję błędy wymienione powyżej. Jeśli jednak build_shared_libs jest zaznaczone, to generuję zestaw .lib i .pliki dll. Kiedy teraz łączy się z nimi .pliki lib program kompiluje, ale po uruchomieniu skarży się, że nie może znaleźć gtest.dll.
To dlatego, że musisz dodać -DGTEST_LINKED_AS_SHARED_LIBRARY=1 do definicji kompilatora w Twoim projekcie, jeśli chcesz użyć gtest jako biblioteki współdzielonej.
Możesz również użyć bibliotek statycznych, pod warunkiem, że skompilujesz je z włączoną opcją gtest_force_shared_crt, aby wyeliminować widoczne błędy.
Podoba mi się biblioteka, ale dodanie jej do projektu to prawdziwy ból. I nie masz szans zrobić tego dobrze, chyba że kopiesz (i zhakujesz) pliki gtest cmake. Szkoda. W szczególności nie podoba mi się pomysł dodania gtest jako źródła. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-19 11:28:08
Twoje i VladLosevs' s rozwiązania są prawdopodobnie lepsze niż moje. Jeśli jednak potrzebujesz rozwiązania brute-force, spróbuj tego:
SET(CMAKE_EXE_LINKER_FLAGS /NODEFAULTLIB:\"msvcprtd.lib;MSVCRTD.lib\")
FOREACH(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
ENDFOREACH(flag_var)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-26 21:32:43
Najprostsze Cmakelisty.txt wyedytowałem z odpowiedzi w tym wątku i jakieś próby i błędy to:
project(test CXX C)
cmake_minimum_required(VERSION 2.6.2)
#include folder contains current project's header filed
include_directories("include")
#test folder contains test files
set (PROJECT_SOURCE_DIR test)
add_executable(hex2base64 ${PROJECT_SOURCE_DIR}/hex2base64.cpp)
# Link test executable against gtest nothing else required
target_link_libraries(hex2base64 gtest pthread)
Gtest powinien być już zainstalowany w Twoim systemie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-24 19:36:06