diff --git a/.gitignore b/.gitignore
index c79e0d153e35d6b063097a957b056815a9c8f10e..0dd6ebd5a1b1c6d937a86849046800be4b0be583 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,7 @@ Makefile.in
 
 # Python
 *.pyc
+*.stamp
 python/opendht.cpp
 python/setup.py
 
@@ -60,3 +61,6 @@ doc/Doxyfile
 # vim swap files
 *.swp
 *.swo
+
+# build dir
+build
diff --git a/.travis.yml b/.travis.yml
index daaf24c01d39adb7cb75ee2eb727acfb5c3d2c6d..de9c3720416066a8c52efcde933ee7917cea23e4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -58,7 +58,7 @@ script:
       else
         options+='-DOPENDHT_PUSH_NOTIFICATIONS=OFF ';
       fi
-      docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON $options .. && make -j8 && make install";
+      docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON -DOPENDHT_TESTS=ON $options .. && make -j8 && ./opendht_unit_tests && make install";
     fi
 
   - |
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cdd49bf72e26f7e042c8bec12d805ea7d4c36720..443a9963846813601463cb70cba6933f7c04a9e2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,7 +20,9 @@ option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restbed and jsoncpp"
 option (OPENDHT_PUSH_NOTIFICATIONS "Enable push notifications support" OFF)
 option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" OFF)
 option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restbed and jsoncpp" OFF)
-option (OPENDHT_INDEX "Build DHT indexation feature" ON)
+option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
+option (OPENDHT_TESTS "Add unit tests executable" OFF)
+
 
 find_package(Doxygen)
 option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
@@ -292,3 +294,26 @@ install (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
 install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
 install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE opendhtConfig.cmake)
 install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht)
+
+# Unit tests
+IF(OPENDHT_TESTS)
+  FIND_PACKAGE(Cppunit REQUIRED)
+  # unit testing
+    add_executable(opendht_unit_tests
+      tests/tests_runner.cpp
+      tests/infohashtester.h
+      tests/infohashtester.cpp
+    )
+    if (OPENDHT_SHARED)
+      TARGET_LINK_LIBRARIES(opendht_unit_tests opendht)
+    else ()
+    	TARGET_LINK_LIBRARIES(opendht_unit_tests opendht-static)
+    endif ()
+    TARGET_LINK_LIBRARIES(opendht_unit_tests
+       ${CMAKE_THREAD_LIBS_INIT}
+       ${CPPUNIT_LIBRARIES}
+       ${GNUTLS_LIBRARIES}
+    )
+    enable_testing()
+    add_test(TEST opendht_unit_tests)
+ENDIF()
diff --git a/Makefile.am b/Makefile.am
index 374856504330a1b9904ccd37a17dbef310fffd12..d16800ad7d144dc71f81773f9d3a058348739b4c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,7 @@ if USE_CYTHON
 SUBDIRS += python
 endif
 
-SUBDIRS += doc
+SUBDIRS += doc tests
 
 ACLOCAL_AMFLAGS = -I m4
 
diff --git a/cmake/FindCppunit.cmake b/cmake/FindCppunit.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..d734a73dc56918dada84d91aa6816d9c0b0df12a
--- /dev/null
+++ b/cmake/FindCppunit.cmake
@@ -0,0 +1,28 @@
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
+
+FIND_PATH(CPPUNIT_INCLUDE_DIRS
+    NAMES cppunit/TestCase.h
+    HINTS ${PC_CPPUNIT_INCLUDE_DIR}
+    ${CMAKE_INSTALL_PREFIX}/include
+    PATHS
+    /usr/local/include
+    /usr/include
+)
+
+FIND_LIBRARY(CPPUNIT_LIBRARIES
+    NAMES cppunit
+    HINTS ${PC_CPPUNIT_LIBDIR}
+    ${CMAKE_INSTALL_PREFIX}/lib
+    ${CMAKE_INSTALL_PREFIX}/lib64
+    PATHS
+    ${CPPUNIT_INCLUDE_DIRS}/../lib
+    /usr/local/lib
+    /usr/lib
+)
+
+LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS})
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
+MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
diff --git a/configure.ac b/configure.ac
index 604d985e7bc704fef398bb7549259c6dab6dc4e0..2611275746b619722724f28a67e985f9eea0569d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -182,6 +182,11 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
 	LDFLAGS="${LDFLAGS} ${Jsoncpp_LIBS} -lrestbed"
 ], [])
 
+AC_ARG_ENABLE([tests], AS_HELP_STRING([--enable-tests], [Enable tests]), build_tests=yes, build_tests=no)
+AM_CONDITIONAL(OPENDHT_TESTS, test x$build_tests == xyes)
+AM_COND_IF([OPENDHT_TESTS], [
+	PKG_CHECK_MODULES([CppUnit], [cppunit >= 1.12])
+])
 
 AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
 
@@ -197,5 +202,6 @@ AM_COND_IF([USE_CYTHON], [
 AC_CONFIG_FILES([Makefile
                  src/Makefile
                  tools/Makefile
+								 tests/Makefile
                  opendht.pc])
 AC_OUTPUT
diff --git a/docker/DockerfileDeps b/docker/DockerfileDeps
index ed0f55821420d6e9bda2a27e1ad70758704e52e3..9b7dc46621cc6bfc2ac08d97460140f42ca04445 100644
--- a/docker/DockerfileDeps
+++ b/docker/DockerfileDeps
@@ -1,3 +1,3 @@
 FROM ubuntu:17.04
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
-RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools && apt-get clean
\ No newline at end of file
+RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev libcppunit-dev python3-setuptools && apt-get clean
diff --git a/docker/DockerfileDepsLlvm b/docker/DockerfileDepsLlvm
index ab2dedc390f86f965af2511c5908d06d86f6a7ec..5dc9fb564490643da97e93a91900e0878377c6fe 100644
--- a/docker/DockerfileDepsLlvm
+++ b/docker/DockerfileDepsLlvm
@@ -1,7 +1,7 @@
 FROM ubuntu:17.04
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
 RUN apt-get update \
-	&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools \
+	&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libargon2-0-dev cython3 python3-dev python3-setuptools libcppunit-dev \
 	&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
 ENV CC cc
-ENV CXX c++
\ No newline at end of file
+ENV CXX c++
diff --git a/docker/DockerfileTravis b/docker/DockerfileTravis
index 693827eb0dc0469e9fac2b57b3216de29f59c319..840e4ccd2b622c243ba6585c8a267b500ac2f9cd 100644
--- a/docker/DockerfileTravis
+++ b/docker/DockerfileTravis
@@ -1,5 +1,9 @@
 FROM aberaud/opendht-deps
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+
+RUN apt-get install -y libcppunit-dev # temp while aberaud/opendht-deps doesn't have this
+
 COPY . /root/opendht
 RUN cd /root/opendht && mkdir build && cd build \
-	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On .. && make -j8 && make install
+	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On -DOPENDHT_TESTS=ON ..  \
+	&& make -j8 && ./opendht_unit_tests && make install
diff --git a/docker/DockerfileTravisLlvm b/docker/DockerfileTravisLlvm
index c32a9fd8df95f649ee4463436a20458e6dd9a6bf..b4a443e6a55857de9869fe2ab39d34c28388e881 100644
--- a/docker/DockerfileTravisLlvm
+++ b/docker/DockerfileTravisLlvm
@@ -1,5 +1,9 @@
 FROM aberaud/opendht-deps-llvm
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+
+RUN apt-get install -y libcppunit-dev # temp while aberaud/opendht-deps doesn't have this
+
 COPY . /root/opendht
 RUN cd /root/opendht && mkdir build && cd build \
-	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On .. && make -j8 && make install
+	&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_TESTS=ON .. \
+	&& make -j8 && ./opendht_unit_tests && make install
diff --git a/docker/DockerfileTravisProxy b/docker/DockerfileTravisProxy
index b543e61afba4947878732fd959019f84bbf0bc51..551217b7e676215a393e41f6d821c424f5aaca10 100644
--- a/docker/DockerfileTravisProxy
+++ b/docker/DockerfileTravisProxy
@@ -1,3 +1,6 @@
 FROM opendht-deps-proxy
 MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+
+RUN apt-get install -y libcppunit-dev # temp while aberaud/opendht-deps doesn't have this
+
 COPY . /root/opendht
diff --git a/include/opendht/infohash.h b/include/opendht/infohash.h
index ade90dc30c333353650bce15f9e5c9e6046d1607..e82613f5c177310a5becd75253969fff3ef26593 100644
--- a/include/opendht/infohash.h
+++ b/include/opendht/infohash.h
@@ -129,7 +129,7 @@ public:
      * Find the lowest 1 bit in an id.
      * Result will allways be lower than 8*N
      */
-    inline unsigned lowbit() const {
+    inline int lowbit() const {
         int i, j;
         for(i = N-1; i >= 0; i--)
             if(data_[i] != 0)
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..16660000032237f5fbcabc352b013a4a9049972c
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,9 @@
+if OPENDHT_TESTS
+bin_PROGRAMS = opendht_unit_tests
+
+AM_CPPFLAGS = -I../include
+
+opendht_unit_tests_SOURCES = tests_runner.cpp infohashtester.cpp
+opendht_unit_tests_HEADERS = infohashtester.h
+opendht_unit_tests_LDFLAGS = -lopendht -lcppunit  -L@top_builddir@/src/.libs @Argon2_LDFLAGS@ @GnuTLS_LIBS@
+endif
diff --git a/tests/infohashtester.cpp b/tests/infohashtester.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d8f116c48562cb0431f27c5cb954ed350a7d485
--- /dev/null
+++ b/tests/infohashtester.cpp
@@ -0,0 +1,145 @@
+/*
+ *  Copyright (C) 2018 Savoir-faire Linux Inc.
+ *
+ *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include "infohashtester.h"
+
+// std
+#include <iostream>
+#include <string>
+
+// opendht
+#include "infohash.h"
+
+namespace test {
+CPPUNIT_TEST_SUITE_REGISTRATION(InfoHashTester);
+
+void
+InfoHashTester::setUp() {
+
+}
+
+void
+InfoHashTester::testConstructors() {
+    // Default constructor creates a null infohash
+    auto nullHash = dht::InfoHash();
+    CPPUNIT_ASSERT(nullHash.size() == 20);
+    CPPUNIT_ASSERT(!nullHash);
+    // Build from a uint8_t. if length to short, should get a null infohash
+    uint8_t to_short[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
+    auto infohash = dht::InfoHash(to_short, 8);
+    CPPUNIT_ASSERT(infohash.size() == 20);
+    CPPUNIT_ASSERT_EQUAL(infohash.toString(),
+        std::string("0000000000000000000000000000000000000000"));
+    // Build from a uint8_t. if length is enough, data should contains the uint8_t
+    uint8_t enough[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
+                        0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
+    infohash = dht::InfoHash(enough, 20);
+    CPPUNIT_ASSERT(infohash.size() == 20);
+    const auto* data = infohash.data();
+    for (auto i = 0; i < 20; ++i) {
+        CPPUNIT_ASSERT_EQUAL(enough[i], data[i]);
+    }
+    // if too long, should be cutted to 20
+    uint8_t tooLong[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
+                        0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb0};
+    infohash = dht::InfoHash(tooLong, 21);
+    CPPUNIT_ASSERT(infohash.size() == 20);
+    const auto* data2 = infohash.data();
+    for (auto i = 0; i < 20; ++i) {
+        CPPUNIT_ASSERT_EQUAL(enough[i], data2[i]);
+    }
+    // Build from string
+    auto infohashFromStr = dht::InfoHash("0102030405060708090A0102030405060708090A");
+    CPPUNIT_ASSERT(infohashFromStr.size() == 20);
+    const auto* dataStr = infohashFromStr.data();
+    for (auto i = 0; i < 20; ++i) {
+        CPPUNIT_ASSERT_EQUAL((int)dataStr[i], (int)data[i]);
+    }
+}
+
+void
+InfoHashTester::testComperators() {
+    auto nullHash = dht::InfoHash();
+    auto minHash = dht::InfoHash("0000000000000000000000000000000000111110");
+    auto maxHash = dht::InfoHash("0111110000000000000000000000000000000000");
+    // operator ==
+    CPPUNIT_ASSERT_EQUAL(minHash, minHash);
+    CPPUNIT_ASSERT_EQUAL(minHash, dht::InfoHash("0000000000000000000000000000000000111110"));
+	CPPUNIT_ASSERT(!(minHash == maxHash));
+    // operator !=
+    CPPUNIT_ASSERT(!(minHash != minHash));
+    CPPUNIT_ASSERT(!(minHash != dht::InfoHash("0000000000000000000000000000000000111110")));
+	CPPUNIT_ASSERT(minHash != maxHash);
+    // operator<
+    CPPUNIT_ASSERT(nullHash < minHash);
+    CPPUNIT_ASSERT(nullHash < maxHash);
+    CPPUNIT_ASSERT(minHash < maxHash);
+    CPPUNIT_ASSERT(!(minHash < nullHash));
+    CPPUNIT_ASSERT(!(maxHash < nullHash));
+    CPPUNIT_ASSERT(!(maxHash < minHash));
+    CPPUNIT_ASSERT(!(minHash < minHash));
+    // bool()
+    CPPUNIT_ASSERT(maxHash);
+    CPPUNIT_ASSERT(!nullHash);
+
+}
+
+void
+InfoHashTester::testLowBit() {
+    auto nullHash = dht::InfoHash();
+    auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
+    auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
+    CPPUNIT_ASSERT_EQUAL(nullHash.lowbit(), -1);
+    CPPUNIT_ASSERT_EQUAL(minHash.lowbit(), 155);
+    CPPUNIT_ASSERT_EQUAL(maxHash.lowbit(), 7);
+}
+
+void
+InfoHashTester::testCommonBits() {
+    auto nullHash = dht::InfoHash();
+    auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
+    auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
+    CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, nullHash), (unsigned)160);
+    CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, minHash), (unsigned)155);
+    CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(nullHash, maxHash), (unsigned)7);
+    CPPUNIT_ASSERT_EQUAL(dht::InfoHash::commonBits(minHash, maxHash), (unsigned)7);
+}
+
+void
+InfoHashTester::testXorCmp() {
+    auto nullHash = dht::InfoHash();
+    auto minHash = dht::InfoHash("0000000000000000000000000000000000000010");
+    auto maxHash = dht::InfoHash("0100000000000000000000000000000000000000");
+    CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(nullHash, maxHash), -1);
+    CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(maxHash, nullHash), 1);
+    CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(minHash, maxHash), -1);
+    CPPUNIT_ASSERT_EQUAL(minHash.xorCmp(maxHash, minHash), 1);
+    CPPUNIT_ASSERT_EQUAL(nullHash.xorCmp(minHash, maxHash), -1);
+    CPPUNIT_ASSERT_EQUAL(nullHash.xorCmp(maxHash, minHash), 1);
+    // Because hashes are circular in distance.
+    CPPUNIT_ASSERT_EQUAL(maxHash.xorCmp(nullHash, minHash), -1);
+    CPPUNIT_ASSERT_EQUAL(maxHash.xorCmp(minHash, nullHash), 1);
+}
+
+void
+InfoHashTester::tearDown() {
+
+}
+}  // namespace test
diff --git a/tests/infohashtester.h b/tests/infohashtester.h
new file mode 100644
index 0000000000000000000000000000000000000000..2558d3afc6fcffeb0c2fb16a49875688ea30579c
--- /dev/null
+++ b/tests/infohashtester.h
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (C) 2018 Savoir-faire Linux Inc.
+ *
+ *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#pragma once
+
+// cppunit
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace test {
+
+class InfoHashTester : public CppUnit::TestFixture {
+    CPPUNIT_TEST_SUITE(InfoHashTester);
+    CPPUNIT_TEST(testConstructors);
+    CPPUNIT_TEST(testComperators);
+    CPPUNIT_TEST(testLowBit);
+    CPPUNIT_TEST(testCommonBits);
+    CPPUNIT_TEST(testXorCmp);
+    CPPUNIT_TEST_SUITE_END();
+
+ public:
+    /**
+     * Method automatically called before each test by CppUnit
+     */
+    void setUp();
+    /**
+     * Method automatically called after each test CppUnit
+     */
+    void tearDown();
+    /**
+     * Test the differents behaviors of constructors
+     */
+    void testConstructors();
+    /**
+     * Test compare operators
+     */
+    void testComperators();
+    /**
+     * Test lowbit method
+     */
+    void testLowBit();
+    /**
+     * Test commonBits method
+     */
+    void testCommonBits();
+    /**
+     * Test xorCmp operators
+     */
+    void testXorCmp();
+
+};
+
+}  // namespace test
diff --git a/tests/tests_runner.cpp b/tests/tests_runner.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dffdc8c9ecd2c307f56bebf2c0bafa31d9a9cd50
--- /dev/null
+++ b/tests/tests_runner.cpp
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2017-2018 Savoir-faire Linux Inc.
+ *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/CompilerOutputter.h>
+#include <iostream>
+
+int main(int argc, char** argv) {
+    CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
+    CppUnit::Test *suite = registry.makeTest();
+    if (suite->countTestCases() == 0) {
+        std::cout << "No test cases specified for suite" << std::endl;
+        return 1;
+    }
+    CppUnit::TextUi::TestRunner runner;
+    runner.addTest(suite);
+    auto result = runner.run() ? 0 : 1;
+    return result;
+}