Skip to content
Snippets Groups Projects
Commit 33edd5c5 authored by Joan Solà Ortega's avatar Joan Solà Ortega
Browse files

Merge branch 'gtest' into 'master'

Gtest

Add unit testing to wolf with googletest.

If the `BUILD_TESTS` option is enable in the top level `CMakeLists.txt` it will retrieve googletest from github and compiles it.

Then all wolf-tests present in the `test` folder are compiled in one single executable.
This executable can be break-down into smaller chunks - see `test/CMakeLists.txt`

Provide a very simple test as an example.

See merge request !82
parents 9b363aa7 f4776a25
No related branches found
No related tags found
1 merge request!82Gtest
......@@ -36,7 +36,7 @@ SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
SET(CMAKE_INSTALL_PREFIX /usr/local)
IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "DEBUG")
SET(CMAKE_BUILD_TYPE "RELEASE")
ENDIF (NOT CMAKE_BUILD_TYPE)
message(STATUS "Configured to compile in ${CMAKE_BUILD_TYPE} mode.")
......@@ -65,6 +65,9 @@ else()
endif()
#OPTION(BUILD_DOC "Build Documentation" OFF)
OPTION(BUILD_TESTS "Build Unit tests" ON)
ADD_SUBDIRECTORY(src)
FIND_PACKAGE(Doxygen)
......@@ -124,3 +127,17 @@ ELSE(UNIX)
TARGET uninstall)
ENDIF(UNIX)
#############
## Testing ##
#############
if(BUILD_TESTS)
# Enables testing for this directory and below.
# Note that ctest expects to find a test file in the build directory root.
# Therefore, this command should be in the source directory root.
enable_testing()
add_subdirectory(${PROJECT_SOURCE_DIR}/test)
endif()
......@@ -31,6 +31,8 @@ option(BUILD_EXAMPLES "Build examples" ON)
FIND_PACKAGE(Eigen 3 REQUIRED)
FIND_PACKAGE(Threads REQUIRED)
FIND_PACKAGE(Ceres QUIET) #Ceres is not required
IF(Ceres_FOUND)
MESSAGE("Ceres Library FOUND: Ceres related sources will be built.")
......@@ -395,10 +397,9 @@ IF(YAMLCPP_FOUND)
ENDIF(laser_scan_utils_FOUND)
ENDIF(YAMLCPP_FOUND)
# create the shared library
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${SRCS_WRAPPER})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
#Link the created libraries
#=============================================================
......
# Retrieve googletest from github & compile
add_subdirectory(${PROJECT_SOURCE_DIR}/test/gtest)
# Include config.h directory at first.
include_directories(${PROJECT_BINARY_DIR}/conf/)
include_directories(${GTEST_INCLUDE_DIRS})
# Create a specific test executable for gtest_example
wolf_add_gtest(gtest_example gtest_example.cpp)
target_link_libraries(gtest_example ${PROJECT_NAME})
wolf_add_gtest(gtest_time_stamp gtest_time_stamp.cpp)
target_link_libraries(gtest_time_stamp ${PROJECT_NAME})
cmake_minimum_required(VERSION 2.8.8)
project(gtest_builder C CXX)
# We need thread support
#find_package(Threads REQUIRED)
# Enable ExternalProject CMake module
include(ExternalProject)
set(GTEST_FORCE_SHARED_CRT ON)
set(GTEST_DISABLE_PTHREADS OFF)
# For some reason I need to disable PTHREADS
# with g++ (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3
# This is a known issue for MinGW :
# https://github.com/google/shaderc/pull/174
#if(MINGW)
set(GTEST_DISABLE_PTHREADS ON)
#endif()
# Download GoogleTest
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs
-DCMAKE_CXX_FLAGS=${MSVC_COMPILER_DEFS}
-Dgtest_force_shared_crt=${GTEST_FORCE_SHARED_CRT}
-Dgtest_disable_pthreads=${GTEST_DISABLE_PTHREADS}
-DBUILD_GTEST=ON
PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
# Disable install step
INSTALL_COMMAND ""
)
# Get GTest source and binary directories from CMake project
# Specify include dir
ExternalProject_Get_Property(googletest source_dir)
set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include PARENT_SCOPE)
# Specify MainTest's link libraries
ExternalProject_Get_Property(googletest binary_dir)
set(GTEST_LIBS_DIR ${binary_dir}/googlemock/gtest PARENT_SCOPE)
# Create a libgtest target to be used as a dependency by test programs
add_library(libgtest IMPORTED STATIC GLOBAL)
add_dependencies(libgtest googletest)
# Set libgtest properties
set_target_properties(libgtest PROPERTIES
"IMPORTED_LOCATION" "${binary_dir}/googlemock/gtest/libgtest.a"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
)
function(wolf_add_gtest target)
add_executable(${target} ${ARGN})
add_dependencies(${target} libgtest)
target_link_libraries(${target} libgtest)
#WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
add_test(NAME ${target} COMMAND ${target})
endfunction()
#include "utils_gtest.h"
TEST(TestTest, DummyTestExample)
{
EXPECT_FALSE(false);
ASSERT_TRUE(true);
int my_int = 5;
ASSERT_EQ(my_int, 5);
PRINTF("All good at TestTest::DummyTestExample !\n");
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include "utils_gtest.h"
#include "../src/time_stamp.h"
#include <thread>
TEST(WolfTestTimeStamp, TimeStampInitNow)
{
wolf::TimeStamp start;
// If we don't sleep, start == time_stamp sometimes.
// And sometimes start <= time_stamp ...
std::this_thread::sleep_for(std::chrono::microseconds(1));
ASSERT_NE(start.get(), 0);
wolf::TimeStamp time_stamp;
// std::cout << std::fixed;
// std::cout << std::setprecision(15);
// std::cout << start.get() << " | " << time_stamp.get() << std::endl;
ASSERT_NE(time_stamp.get(), start.get());
ASSERT_LT(start.get(), time_stamp.get());
PRINTF("All good at WolfTestTimeStamp::TimeStampInitNow !\n");
}
TEST(WolfTestTimeStamp, TimeStampInitScalar)
{
wolf::Scalar val(101010);
wolf::TimeStamp start(val);
ASSERT_EQ(start.get(), val);
ASSERT_EQ(start.getSeconds(), val);
ASSERT_EQ(start.getNanoSeconds(), 0);
std::stringstream ss;
start.print(ss);
ASSERT_STREQ("101010.0000000000", ss.str().c_str());
PRINTF("All good at WolfTestTimeStamp::TimeStampInitScalar !\n");
}
TEST(WolfTestTimeStamp, TimeStampInitScalarSecNano)
{
wolf::Scalar sec(101010);
wolf::Scalar nano(202020);
wolf::Scalar val(101010.000202020);
wolf::TimeStamp start(sec, nano);
// start.get -> 101010.000202020004508
ASSERT_EQ(start.get(), val);
ASSERT_EQ(start.getSeconds(), sec);
ASSERT_EQ(start.getNanoSeconds(), nano);
std::stringstream ss;
start.print(ss);
ASSERT_STREQ("101010.0002020200", ss.str().c_str());
PRINTF("All good at WolfTestTimeStamp::TimeStampInitScalarSecNano !\n");
}
TEST(WolfTestTimeStamp, TimeStampEquality)
{
wolf::TimeStamp start;
wolf::TimeStamp time_stamp(start);
// error: no match for ‘operator==’
//ASSERT_EQ(time_stamp, start);
ASSERT_EQ(time_stamp.get(), start.get());
time_stamp.setToNow();
ASSERT_NE(time_stamp.get(), start.get());
time_stamp = start;
ASSERT_EQ(time_stamp.get(), start.get());
PRINTF("All good at WolfTestTimeStamp::TimeStampEquality !\n");
}
TEST(WolfTestTimeStamp, TimeStampInequality)
{
wolf::TimeStamp start;
std::this_thread::sleep_for(std::chrono::microseconds(1));
wolf::TimeStamp time_stamp;
// error: no match for ‘operator!=’
//ASSERT_NE(time_stamp, start);
ASSERT_LT(start, time_stamp);
// error: no match for ‘operator>’
//ASSERT_GT(time_stamp, start);
PRINTF("All good at WolfTestTimeStamp::TimeStampInequality !\n");
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
/**
* \file utils_gtest.h
* \brief Some utils for gtest
* \author Jeremie Deray
* Created on: 26/09/2016
*/
#ifndef WOLF_UTILS_GTEST_H
#define WOLF_UTILS_GTEST_H
#include <gtest/gtest.h>
// Macros for testing equalities and inequalities.
//
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2
// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2
// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2
// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2
// http://stackoverflow.com/a/29155677
namespace testing
{
namespace internal
{
enum GTestColor
{
COLOR_DEFAULT,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW
};
extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
#define PRINTF(...) \
do { testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN,\
"[ ] "); \
testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, __VA_ARGS__); } \
while(0)
// C++ stream interface
class TestCout : public std::stringstream
{
public:
~TestCout()
{
PRINTF("%s\n", str().c_str());
}
};
#define TEST_COUT testing::internal::TestCout()
} // namespace internal
} // namespace testing
/** Usage :
TEST(Test, Foo)
{
// the following works but prints default stream
EXPECT_TRUE(false) << "Testing Stream.";
// or you can play with AINSI color code
EXPECT_TRUE(false) << "\033[1;31m" << "Testing Stream.";
// or use the above defined macros
PRINTF("Hello world");
// or
TEST_COUT << "Hello world";
}
*/
#endif /* WOLF_UTILS_GTEST_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment