How do I configure GTest to work with the graphical debugger in Visual Studio Code? - c++

All I want is to be able to click on the cute bug in Visual Studio Code and step through my code to figure out why my Gtest tests are failing.
I don't want to use the submodule approach specified in this question.
How do I do this?

Assuming a directory structure of
myproject
| -- CMakeLists.txt
| -- hello_test.cpp
with hello_test.cpp looking like:
#include <gtest/gtest.h>
TEST(hello_test, add)
{
GTEST_ASSERT_EQ((10 + 22), 32);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Your CMakeLists.txt should look like:
cmake_minimum_required(VERSION 3.0.0)
project(myproject VERSION 0.1.0)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
include(FetchContent)
FetchContent_Declare(
googletest
# Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/5376968f6948923e2411081fd9372e71a59d8e77.zip
)
FetchContent_MakeAvailable(googletest)
add_executable(hello_test hello_test.cpp)
target_link_libraries(
hello_test
gtest
)
include(GoogleTest)
gtest_discover_tests(hello_test)

Related

Adding GoogleTest to existing project give linker errors

I have a project that uses CMake to get built. I wanted to test my program using GoogleTest.
So I followed the instructions of the ReadMe file of GoogleTest, and added the marked lines to my CMakeLists.txt (My OS is Ubuntu 20.04.3 LTS) :
cmake_minimum_required(VERSION 3.20)
project(replicatorProject)
set(CMAKE_CXX_STANDARD 14)
### I added the the following lines which I got from the ReadMe of GoogleTest
include(FetchContent)
FetchContent_Declare(
googletest
# Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable(example test/CrushMapperTest.cpp)
target_link_libraries(example gtest_main)
add_test(NAME example_test COMMAND example)
### until here (above)
find_library(CRUSH_LIBRARY libcrush.so /usr/local/lib/crush/ REQUIRED)
find_package(CppKafka REQUIRED)
add_executable(replicator src/main.cpp src/kafka/KafkaConsumer.cpp src/kafka/KafkaConsumer.h src/crush/CrushMapper.cpp src/crush/CrushMapper.h src/Replicator.cpp src/Replicator.h src/crush/Bucket.cpp src/crush/Bucket.h src/crush/Device.cpp src/crush/Device.h)
target_link_libraries(replicator LINK_PUBLIC ${CRUSH_LIBRARY} CppKafka::cppkafka)
target_include_directories(replicator PRIVATE /usr/local/include)
My Project structure looks like this:
CrushMapperTest.cpp looks like the following:
#include "gtest/gtest.h"
int main(int argc, char **argv){
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
TEST(case1, name){
EXPECT_EQ(1,1);
}
However, if I run the test, I get a lot of undefined reference errors from my linker (here are some of them):
/usr/bin/ld: /home/lorik/Uni/Praktikum/Projekt/replicator/test/CrushMapperTest.cpp:13: undefined reference to `testing::internal::AssertHelper::~AssertHelper()'
/usr/bin/ld: /home/lorik/Uni/Praktikum/Projekt/replicator/test/CrushMapperTest.cpp:13: undefined reference to `testing::internal::AssertHelper::~AssertHelper()'
Now I am new to using CMake and I don't get what else I need to add to make the linker find the Google Test functions. I was looking through some other SO posts with similar problems ( like this one) a while ago , but so far no suggested solution helped while trying to dowload google test directly through CMake.
What am I doing wrong? Do I need another CMakeLists.txt for the test directory?
Solution
I had to add FetchContent_MakeAvailable(googletest) after the FetchContent_Declare(...) line

Error running google test on default in CLion

So, unfortunatly I am unsure how to properly describe the error message.
Essentially I am trying to get used to google test, - I want to use it to test my C++ project in CLion. I create a new library project, with the following classes:
#include "gtest/gtest.h"
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
and also:
#include "gtest/gtest.h"
TEST(MyTestCategory, Vec2DAdditionTest){
EXPECT_EQ(1, 1);
}
Of course these tests are not useful at all - but its just to see if everything works the way it should.
Now when I tried to run them, I am prompted the following error:
6:46 PM Error running 'MyTestCategory.Vec2DAdditionTest': Cannot run 'MyTestCategory.Vec2DAdditionTest' on '<default>'
6:47 PM Error running 'All in main.cpp': Cannot run 'All in main.cpp' on '<default>'
What am I missing? I can't get the tests to run, - neither individually, nor directly over the main function?
Also after this, the build/run button gets greyed out in CLion and I have to right click on the main.cpp to force it to run/compile..
Essential I have a project structure like so:
src/
a.cpp
b.cpp
CMakeLists.txt
test/
main.cpp
atests.cpp
CmakeLists.txt
CMakeLists.txt
My run configuration for the test project looks like so:
Here is an example on how you can add GTests in your CLion project:
Consider a project structure very similar to what you have presented, however, with an additional file CMakeLists.txt.in in the test folder.:
src/
a.cpp
b.cpp
CMakeLists.txt
test/
main.cpp
atests.cpp
CMakeLists.txt
CMakeLists.txt.in
CMakeLists.txt
The CMakeLists.txt.in helps to download and add the GTest libraries to your project while building your project.
The content of CMakeLists.txt.in looks as below:
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
The test/CMakeLists.txt file looks as below:
cmake_minimum_required(VERSION 3.10)
### START OF CONFIGURING GTEST
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
### END OF CONFIGURING GTEST
# Now simply link against gtest or gtest_main as needed. Eg
add_executable(test_${PROJECT_NAME} main.cpp atest.cpp)
target_link_libraries(test_${PROJECT_NAME} ${PROJECT_NAME} gtest gtest_main)
add_test(NAME test_PROJECT_NAME COMMAND test_${PROJECT_NAME})
CMakeLists.txt in the root folder has the following content:
cmake_minimum_required(VERSION 3.10)
project(gtestTest)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(src)
add_subdirectory(test)
Now reload the CMake configuration and try running the test_gtestTest target to run the unit tests.
You can also create custom run configurations using gtest template of CLion to get user friendly test reports.
For more information on GTests with CLion, please refer to:
Google Test Support in Clion
Building Google Tests with CMake

GTest CMake multiple definition of main

I am trying to learn how to use gtest for creating unit testing in c++. I wrote a simple library to test, where I created a factorial function
src/main.cpp
#include <iostream>
int factorial(int n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}
// Default main function
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
src/main.h
#ifndef GTEST_LEARN_MAIN_H
#define GTEST_LEARN_MAIN_H
int factorial(int n);
#endif //GTEST_LEARN_MAIN_H
src/CMakeLists.txt
add_executable(gtest_learn main.cpp main.h)
add_library(factorial_lib STATIC main.cpp main.h)
Then I created a unit test where I am testing the factorial function
test/main.cpp
#include "main.h"
#include "gtest/gtest.h"
TEST(MyTestSuite,MyTest){
EXPECT_EQ(factorial(4),24);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I added gtest to my project following the docs on the github page
test/CMakeLists.txt.in
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
test/CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(tests)
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# The gtest/gtest_main targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories("${gtest_SOURCE_DIR}/include")
endif()
add_executable(tests main.cpp)
target_link_libraries(tests gtest_main)
target_link_libraries(tests factorial_lib)
add_test(NAME example_test COMMAND tests)
When I am trying to run my test, I get an error saying multiple definition of 'main'. It also says the first definition of main was in test/main.cpp, but before I added the main function in this file, it said that main was first declared in googletest-src/googletest/src/gtest_main.cc, which is the gtest library. For this project I could remove the main from src/main since it serves no purpose, but in a real application that wouldn't be an option. I assume I have to make some CMake config to ignore the gtest main or something like that, but I don't know how. Can anyone help me out? Thanks in advance!
Here is my project-level CMakeLists
cmake_minimum_required(VERSION 3.15)
project(gtest_learn)
set(CMAKE_CXX_STANDARD 14)
include_directories(src)
add_subdirectory(src)
add_subdirectory(test)
You have two main functions declared, what I do is:
#ifndef TESTING
// Default main function
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
#endif
#ifdef TESTING
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#endif
For test compilation I declare a TESTING macro, which then ensures, that the compiler sees only one main function. For compiling the application, it does not see the test main.

Getting reference issue in Qt while implementing OpenSceneGraph

I am getting error (**
**> CMakeFiles\untitled3.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x46):
undefined reference to `_imp___ZN9osgViewer6ViewerC1Ev'**)
while adding OpenSceneGraph in Qt. My profile is cmakelist.txt.
cmake_minimum_required(VERSION 2.8.12)
project(untitled3)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Core)
FIND_PATH(OPENSCENEGRAPH_INCLUDE_DIR osg/Referenced
PATHS
$ENV{OSG_ROOT}/include
$ENV{OSG_DIR}/include
/usr/include
/usr/local/include
)
FIND_PATH(OPENSCENEGRAPH_LIB_DIR libosg.so osg.lib
PATHS
$ENV{OSG_ROOT}/lib
$ENV{OSG_DIR}/lib
/usr/lib
/usr/local/lib
)
INCLUDE_DIRECTORIES(common ${OPENSCENEGRAPH_INCLUDE_DIR})
LINK_DIRECTORIES(${OPENSCENEGRAPH_LIB_DIR})
add_executable(${PROJECT_NAME} "main.cpp")
target_link_libraries(${PROJECT_NAME} Qt5::Core)
My main.cpp file is
#include <QCoreApplication>
#include <osgViewer/Viewer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
osgViewer::Viewer viewer;
// viewer.setSceneData( osgDB::readNodeFile("cessna.osg") );
// return viewer.run();
return a.exec();
}
Any folks who can help. I invite them to come forward.
There is a problem with your cmake file. You need to make sure to:
Find the necessary OSG packages (osgViewer in your case).
Link your executable to the target OSG libraries.
Just like you did it for QtCore:
find_package(Qt5Core)
find_package(OpenSceneGraph REQUIRED COMPONENTS osgViewer)
# ...
target_link_libraries(${PROJECT_NAME} Qt5::Core ${OPENSCENEGRAPH_LIBRARIES} )

cmake does not consider -pthread

I am trying to make a testbench to my program using gmock/gtest; Linux/Ubuntu; KDevelop/CMake. From the link error message I conclude that part of the gtest package is missing pthread support.
/home/projects/cpp/gmock/gtest/libgtest.a(gtest-all.cc.o): In function `testing::internal::ThreadLocal<testing::TestPartResultReporterInterface*>::~ThreadLocal()':
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev]+0x16): undefined reference to `pthread_getspecific'
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev]+0x2b): undefined reference to `pthread_key_delete'
I also read
googletest: how to setup?
Using g++ directly, everything works. So, since I am usinc KDevelop/CMake, I suspect either my code or CMake.
In my CMakeLists.txt I do use
add_definitions( -pthread -m64)
However, I do not see any effect in the Makefile.
Am I missing something from my CMakeLists.txt, or CMake does not consider the line above?
My CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_definitions( -Dpthread )
project(ThreadTest)
INCLUDE_DIRECTORIES(gmock/gtest/include)
set ( GTEST_LIBS libgtest.a )
link_directories( ~/projects/cpp/gmock/gtest)
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${GTEST_LIBS})
Do I misunderstand, that add_definitions should work in this situation?
After reading
How do I force cmake to include "-pthread" option during compilation?
my question really looks like duplicate. However,
cmake_minimum_required(VERSION 2.8)
add_definitions( -Dpthread )
project(ThreadTest)
INCLUDE_DIRECTORIES(gmock/gtest/include)
find_package( Threads )
set ( GTEST_LIBS libgtest.a )
link_directories( ~/projects/cpp/gmock/gtest)
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${GTEST_LIBS} ${CMAKE_THREAD_LIBS_INIT})
still gives the warning 'Could NOT find Threads'. I tried to search Ubuntu software center for "threads", with no result. After that, I installed libghc-threads-dev. However, when using
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
I keep receiving 'Could NOT find Threads', as error. What shall I do to satisfy find_package, and why do I have this problem, when the simple Makefile produces what I expect?
PS: my main file:
#include "gmock/gtest/include/gtest/gtest.h"
TEST(blahTest, blah1) {
EXPECT_EQ(1, 1);
}
int main (int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int returnValue;
returnValue = RUN_ALL_TESTS();
return returnValue;
}
After busy hours, I succeeded to compile my supercomplex test program, using KDevelop/CMake/gtest
#include "gtest-1.7.0/include/gtest/gtest.h"
TEST(blahTest, blah1) {
EXPECT_EQ(1, 1);
}
int main (int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
The CMakeLists.txt file that could do the task is
# http://stackoverflow.com/questions/13513905/how-to-properly-setup-googletest-on-linux/13513907#13513907
# http://stackoverflow.com/questions/15193785/how-to-get-cmake-to-recognize-pthread-on-ubuntu
# http://stackoverflow.com/questions/21116622/undefined-reference-to-pthread-key-create-linker-error
# http://stackoverflow.com/questions/1620918/cmake-and-libpthread
# https://meekrosoft.wordpress.com/2009/10/04/testing-c-code-with-the-googletest-framework/
# http://stackoverflow.com/questions/30106608/googletest-cmake-and-make-tests-not-running
# http://stackoverflow.com/questions/13521618/c-project-organisation-with-gtest-cmake-and-doxygen
# http://www.kaizou.org/2014/11/gtest-cmake/
cmake_minimum_required(VERSION 2.8)
project(ThreadTest C CXX)
ADD_SUBDIRECTORY (gtest-1.7.0)
enable_testing()
#set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(GTest REQUIRED)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
if(NOT MSVC)
set(PThreadLib -pthread)
endif()
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${PThreadLib} ${GTEST_LIBRARIES})
#add_test(ThreadTest ThreadTest)
I want to highlight some things: a few valuable links and
project(ThreadTest C CXX) rather than project(ThreadTest)
and
set(PThreadLib -pthread) rather than set(PThreadLib pthread)
I guess the rest can be managed. It could be a good starting point.
I integrated Google Test framework in my own project and this CMake file is working.
# Google C++ Testing Framework
# https://code.google.com/p/googletest/
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
if(WIN32)
# GTest is static compiled by default
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif()
enable_testing()
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${GTEST_BOTH_LIBRARIES})
CMake warning "Could NOT find Threads" is related to a bug:
CMake failing to detect pthreads due to warnings
All you need to do is link with pthread:
target_link_libraries(BUILD_ARTIFACT pthread)
BUILD_ARTIFACT can be your project, or library name. You should add this line after defining your artifact.
For example, if your build artifact is ThreadTest:
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest pthread)