I have a C++ header which contains a class with a method like below. Lets say its a header only library I have.
// MyHeader.hpp
#pragma once
#include <string>
namespace myheaderonlylibrary {
class MyClass {
public:
unsigned int Func1(const std::string& str) {
if (!str.empty())
return 10;
else
return 0;
}
};
}
To test the above method I heve the following gtest source file inside a folder called unittest
which is like the convention followed.
// MyTests.cpp
#include <limits.h>
#include "gtest/gtest.h"
#include "../MyHeader.hpp"
TEST(MyTest, Test_Something) {
myheaderonlylibrary::MyClass my_object;
unsigned int expected_value = 0;
EXPECT_EQ(expected_value, my_object.Func1(""));
}
All I want to do is build the test using Cmake and run the test. So, following is my CMakeLists.txt
.
// CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
set(MyheaderOnlyLibrary_HEADERS
MyHeader.hpp
)
set(MyheaderOnlyLibrary_unittest
unittest/MyTests.cpp
)
find_package(GTest REQUIRED)
enable_testing ()
add_executable(MyheaderOnlyLibraryTests ${MyheaderOnlyLibrary_unittest})
After the above is set, I do a cmake ..
and make
which results with the following error.
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
Question:
I am not a pro in CMake. My question is that if all I want to do is to be able run tests, then should I be doing an add_executable
? Is this correct approach when the only thing I want is to build and run the tests? Seems like the error when calling make
is because add_executable
is looking for main
method like in a normal executable and its not finding it.
What is the correct way to build a test only project where a header file is the only thing to be tested?
How to run the tests after building? Looks like there is a command CTest
to run the tests built using CMake?
Environment:
I am building this on a macOS with clang as the compiler with C++11.
Just like a normal C++ program you need to have a main function to execute, for a googletest unit test you can use the following:
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
This will run your TEST function when executed.
To use ctest to actually run your tests you should have the following lines in your cmake file:
find_package(GTest)
include_directories(${GTEST_INCLUDE_DIRS})
include(CTest)
include(GoogleTest)
enable_testing()
target_link_libraries(testName ${GTEST_LIBRARIES})
gtest_discover_tests(testName)
EDIT: As an easier place to start before jumping into cmake, I would recommend you start with compiling and running your command on the command line. You can do that with the following:
g++ unittest/myunittest.cpp -o unittest/myunittest.out -lgtest -std=c++11
./unittest/myunittest.out
Once you know it works, take a look at cmake’s documentation and reproduce your results with a cmake file. Then you can start to scale up your programs. Understanding how to run these commands through the command line will give you an appreciation and a better understanding of what cmake is doing.