diff --git a/CMakeLists.txt b/CMakeLists.txt
index c451d172dc62acfacb782e70643c4b25b6a26df3..abbbe2263435901db26463bafe1cc5bdaf9bf993 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 54e6a57b33fe505a1dbf94016ce44ab68ea74ebc..cacea95576ec6651a37fdd4cb05e67bab71b0135 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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
 #=============================================================
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f89fb92d9831de007a72e5d3d269513b820b9fc9
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,14 @@
+# 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})
diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6dcfd702d15939724e27b0fdd43c0ab5d1ef87e2
--- /dev/null
+++ b/test/gtest/CMakeLists.txt
@@ -0,0 +1,62 @@
+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()
diff --git a/test/gtest_example.cpp b/test/gtest_example.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c4ae7a14daf9d9923ec040dea90629eb5c32b5d
--- /dev/null
+++ b/test/gtest_example.cpp
@@ -0,0 +1,20 @@
+#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();
+}
diff --git a/test/gtest_time_stamp.cpp b/test/gtest_time_stamp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..39a75e615d59da6519212dcf5fe5d575759f2b56
--- /dev/null
+++ b/test/gtest_time_stamp.cpp
@@ -0,0 +1,114 @@
+#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();
+}
diff --git a/test/utils_gtest.h b/test/utils_gtest.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e792f5a33327dc73dcff5c860f1c9fe53a56709
--- /dev/null
+++ b/test/utils_gtest.h
@@ -0,0 +1,82 @@
+/**
+ * \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 */