Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleTest CMake and Make tests not running

I admit I have a unique situation. We build our application using Make. But my IDE, CLion, uses CMake. So I have tried to set up GoogleTest to run on both (kind of). I can compile my code both ways (using make at the command line and build from my IDE). But from within CLion when I select the test fixture and click the run button, no tests are found and this is what I receive:

Running main() from gtest_main.cc  
[==========] Running 0 tests from 0 test cases.  
[==========] 0 tests from 0 test cases ran. (0 ms total)  
[ PASSED  ] 0 tests.

Process finished with exit code 0

Here is my test fixture:

#include <gtest/gtest.h>
#include "OPProperties.h"

namespace {
// The fixture for testing class OPPropertiesTestTest.
    class OPPropertiesTestTest : public ::testing::Test {
    protected:
        // You can remove any or all of the following functions if its body
        // is empty.

        OPPropertiesTestTest() {
            // You can do set-up work for each test here.
        }

        virtual ~OPPropertiesTestTest() {
            // You can do clean-up work that doesn't throw exceptions here.
        }

        // If the constructor and destructor are not enough for setting up
        // and cleaning up each test, you can define the following methods:

        virtual void SetUp() {
            // Code here will be called immediately after the constructor (right
            // before each test).
        }

        virtual void TearDown() {
            // Code here will be called immediately after each test (right
            // before the destructor).
        }

        // Objects declared here can be used by all tests in the test case for OPPropertiesTestTest.
    };

    TEST_F(OPPropertiesTestTest, ThisTestWillPass) {
        EXPECT_EQ(0, 0);
    }

    TEST_F(OPPropertiesTestTest, ThisTestWillFail) {
        EXPECT_EQ(0, 5);
    }


}  // namespace


int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

Here is my CMakeLists.txt file:

cmake_minimum_required(VERSION 2.8)
project(oneprint)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -lgtest")
add_definitions(-DBOOST_LOG_DYN_LINK)


set(SOURCE_FILES
    src/controllers/OPProperties.cpp
    src/controllers/OPProperties.h
    src/main.cpp)

include_directories(src/controllers)

set(BOOST_ROOT "/usr/local/lib")
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
unset(Boost_INCLUDE_DIR CACHE)
unset(Boost_LIBRARY_DIRS CACHE)
#set(Boost_LIBRARY_DIR /usr/local/arm/lib)
set(OpenCV_LIBRARY_DIR /usr/include/opencv2)
set(Innovatrics_LIBRARY_DIR /usr/local/arm/lib)

find_package(OpenCV REQUIRED)

find_package(Boost 1.57.0 COMPONENTS filesystem thread log chrono system atomic program_options REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})

enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})

add_executable(OnePrint ${SOURCE_FILES})

target_link_libraries(OnePrint ${OpenCV_LIBS})
target_link_libraries(OnePrint ${Boost_LIBRARIES})
target_link_libraries(OnePrint ${Innovatrics_LIBRARY_DIR})
target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})
target_link_libraries(OnePrint pthread)

I've added a folder under src called tests, which is where my test fixture, OPPropertiesTestTest, is located. I've also added a test folder at the top level. Included in this folder is a Makefile and a Srcs.mak file.

Here is the Makefile:

TARGET = oneprint
BASE = ../

-include $(BASE)Defs.x86.mak
-include $(BASE)OpenCV.mak
-include $(BASE)Boost.mak
-include $(BASE)Innovatrics.mak
-include $(BASE)GTest.mak

-include $(BASE)Incl.mak
-include Srcs.mak

-include $(BASE)Common.mak
-include $(BASE)App.mak

Here is the Srcs.mak file:

VPATH = \
../src/controllers:\
../src:\
../src/tests

CPP_SRCS = \
OPProperties.cpp \

# test files
CPP_SRCS += \
OPPropertiesTest.cpp
like image 569
Patricia Avatar asked May 07 '15 16:05

Patricia


1 Answers

I wouldn't normally expect to see makefiles being mixed into a CMake-managed project; it sounds like you have quite a complicated setup?

That aside, I think the root cause here is likely to be twofold. I don't think the test executable in /src/tests/ is actually being built. I can't see anything in your CMakelists.txt which would cause this to be built, so unless you're doing something extra you've not shown us, the test files aren't being compiled.

What perhaps makes it look like they are, is that you're linking the helper lib which gtest provides into your OnePrint target. This helper lib is unusual in that it implements a main() function to save users having to specify their own.

You're doing this in the line

target_link_libraries(OnePrint ${GTEST_BOTH_LIBRARIES})

From the docs GTEST_BOTH_LIBRARIES is a variable containing both libgtest and libgtest-main. You only want libgtest since you've written your own main(). So you should use GTEST_LIBRARIES instead.


Note: There are a few other issues with the CMake code:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -lgtest")

This isn't cross-platform (which may not matter to you) e.g. MSVC won't recognise any of these flags. If it does matter, you'd need to wrap this in an if(UNIX) or if(NOT MSVC) block.

Also, this sets the compiler flags globally, i.e. for every target defined in your project. If you need more fine-grained control, have a look at target_compile_options which lets you specify these per-target.

Another issue is the -lgtest part. This is really a call to the linker to link the gtest library. However, CMake takes care of that for you - you're doing this when you call target_link_libraries(OnePrint ${GTEST_LIBRARIES}).


add_definitions(-DBOOST_LOG_DYN_LINK)

While this is fine, the same comments about this being applied globally applies. The per-target equivalent is target_compile_definitions.


set(BOOST_ROOT "/usr/local/lib")

This is maybe the location of Boost on your machine, but that may well not be the case for other devs. That variable is really meant to be specified by individual users when they invoke CMake (if required... many paths are automatically searched by CMake) - you shouldn't really hard-code paths like this into the CMake file.


target_link_libraries(OnePrint pthread)

Again, pthread wouldn't be appropriate to link if you're using MSVC; this should probably be wrapped in an if block.


The final trivial point is that you can specify more than one dependency in the target_link_libraries command, so you could change these to:

if(NOT MSVC)
  set(PThreadLib pthread)
endif()
target_link_libraries(OnePrint
    ${OpenCV_LIBS}
    ${Boost_LIBRARIES}
    ${Innovatrics_LIBRARY_DIR}
    ${GTEST_LIBRARIES}
    ${PThreadLib})
like image 180
Fraser Avatar answered Oct 26 '22 16:10

Fraser