diff --git a/.travis.yml b/.travis.yml
index 1b3069f0f7d5dd0de1ce03d746c6a7b8c692da33..b421d14a45ac9892b2f8af9d89e1944f2d948017 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,7 @@ env:
     - CTEST_PARALLEL_LEVEL=4
     - CTEST_OUTPUT_ON_FAILURE=1
     - CXX_FLAGS_DEBUG="-O1"
+    - BUILD_PYTHON_INTERFACE=ON
 
 matrix:
   include:
@@ -87,13 +88,17 @@ matrix:
             - eigen
             - octomap
 
+before_install:
+  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then source travis_custom/custom_before_install_linux.sh ; fi
+  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then source travis_custom/custom_before_install_osx.sh ; fi
+
 script:
   # Create build directory
   - mkdir build
   - cd build
 
   # Configure
-  - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS=-w -DCMAKE_CXX_FLAGS_DEBUG=${CXX_FLAGS_DEBUG} ..
+  - cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS=-w -DCMAKE_CXX_FLAGS_DEBUG=${CXX_FLAGS_DEBUG} -DBUILD_PYTHON_INTERFACE=${BUILD_PYTHON_INTERFACE} ..
 
   # Build
   - make -j4
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 145e703686891fc64b11d12d78e95146296a3c3c..c677bc1de701d543d72f178f1e1b14086796d02c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,7 +58,7 @@ IF(APPLE)
   endif("${isSystemDir}" STREQUAL "-1")
 ENDIF(APPLE)
 
-OPTION(BUILD_PYTHON_INTERFACE OFF)
+OPTION(BUILD_PYTHON_INTERFACE "Build the python bindings" OFF)
 
 # Tell CMake that we compute the PROJECT_VERSION manually.
 CMAKE_POLICY(SET CMP0048 OLD)
diff --git a/python/collision-geometries.cc b/python/collision-geometries.cc
index 230cb7b178fda76c9c65e2ac8e0684dbcc5fa932..7d3b63f9138b047a562c9406dec8b382e12aea5c 100644
--- a/python/collision-geometries.cc
+++ b/python/collision-geometries.cc
@@ -114,7 +114,9 @@ void exposeShapes ()
     ("Box", init<>())
     .def (init<FCL_REAL,FCL_REAL,FCL_REAL>())
     .def (init<Vec3f>())
-    .def_readwrite ("halfSide", &Box::halfSide)
+    .add_property("halfSide",
+                  make_getter(&Box::halfSide, return_value_policy<return_by_value>()),
+                  make_setter(&Box::halfSide, return_value_policy<return_by_value>()));
     ;
 
   class_ <Capsule, bases<ShapeBase>, shared_ptr<Capsule> >
diff --git a/python/math.cc b/python/math.cc
index 2edaf3605a07910404cd87039aac2d418daa7550..0b47a345ce5f938cbea72fb258be5ae67c05c119 100644
--- a/python/math.cc
+++ b/python/math.cc
@@ -69,9 +69,6 @@ void exposeMaths ()
   if(!eigenpy::register_symbolic_link_to_registered_type<Eigen::AngleAxisd>())
     eigenpy::exposeAngleAxis();
 
-  eigenpy::enableEigenPySpecific<Matrix3f>();
-  eigenpy::enableEigenPySpecific<Vec3f   >();
-
   class_ <Transform3f> ("Transform3f", init<>())
     .def (init<Matrix3f, Vec3f>())
     .def (init<Quaternion3f, Vec3f>())
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 80a174031222fd1bde12d5deb9687899c1d32f8a..2db77cc854e5afe7f8d759de2a459e4149a9338e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -57,3 +57,8 @@ endif(HPP_FCL_HAVE_OCTOMAP)
 ## Benchmark
 add_executable(test-benchmark benchmark.cpp)
 target_link_libraries(test-benchmark hpp-fcl ${Boost_LIBRARIES} utility)
+
+## Python tests
+IF(BUILD_PYTHON_INTERFACE)
+  ADD_SUBDIRECTORY(python_unit)
+ENDIF(BUILD_PYTHON_INTERFACE)
diff --git a/test/python_unit/CMakeLists.txt b/test/python_unit/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6d62837aee6187fd6b7e0d3665b3090cc6e0efb2
--- /dev/null
+++ b/test/python_unit/CMakeLists.txt
@@ -0,0 +1,7 @@
+SET(${PROJECT_NAME}_PYTHON_TESTS
+  geometric_shapes
+  )
+
+FOREACH(TEST ${${PROJECT_NAME}_PYTHON_TESTS})
+  ADD_PYTHON_UNIT_TEST("py-${TEST}" "test/python_unit/${TEST}.py" "python")
+ENDFOREACH(TEST ${${PROJECT_NAME}_PYTHON_TESTS})
diff --git a/test/python_unit/geometric_shapes.py b/test/python_unit/geometric_shapes.py
new file mode 100644
index 0000000000000000000000000000000000000000..466d92e3747ce36d417ea623ff5c82ec608d9dd5
--- /dev/null
+++ b/test/python_unit/geometric_shapes.py
@@ -0,0 +1,80 @@
+import unittest
+import hppfcl
+hppfcl.switchToNumpyMatrix()
+import numpy as np
+
+class TestGeometricShapes(unittest.TestCase):
+
+    def test_capsule(self):
+        capsule = hppfcl.Capsule(1.,2.)
+        self.assertIsInstance(capsule, hppfcl.Capsule)
+        self.assertIsInstance(capsule, hppfcl.ShapeBase)
+        self.assertIsInstance(capsule, hppfcl.CollisionGeometry)
+        self.assertEqual(capsule.getNodeType(), hppfcl.NODE_TYPE.GEOM_CAPSULE)
+        self.assertEqual(capsule.radius,1.)
+        self.assertEqual(capsule.lz,2.)
+        capsule.radius = 3.
+        capsule.lz = 4.
+        self.assertEqual(capsule.radius,3.)
+        self.assertEqual(capsule.lz,4.)
+
+    def test_box1(self):
+        box = hppfcl.Box(np.matrix([1.,2.,3.]).T)
+        self.assertIsInstance(box, hppfcl.Box)
+        self.assertIsInstance(box, hppfcl.ShapeBase)
+        self.assertIsInstance(box, hppfcl.CollisionGeometry)
+        self.assertEqual(box.getNodeType(), hppfcl.NODE_TYPE.GEOM_BOX)
+        self.assertTrue(np.array_equal(box.halfSide,np.matrix([.5,1.,1.5]).T))
+        box.halfSide = np.matrix([4.,5.,6.]).T
+        self.assertTrue(np.array_equal(box.halfSide,np.matrix([4.,5.,6.]).T))
+
+    def test_box2(self):
+        box = hppfcl.Box(1.,2.,3)
+        self.assertIsInstance(box, hppfcl.Box)
+        self.assertIsInstance(box, hppfcl.ShapeBase)
+        self.assertIsInstance(box, hppfcl.CollisionGeometry)
+        self.assertEqual(box.getNodeType(), hppfcl.NODE_TYPE.GEOM_BOX)
+        self.assertEqual(box.halfSide[0],0.5)
+        self.assertEqual(box.halfSide[1],1.0)
+        self.assertEqual(box.halfSide[2],1.5)
+        box.halfSide[0] = 4.
+        box.halfSide[0] = 5.
+        box.halfSide[0] = 6.
+#         self.assertEqual(box.halfSide[0],4.)
+#         self.assertEqual(box.halfSide[1],5.)
+#         self.assertEqual(box.halfSide[2],6.)
+
+    def test_sphere(self):
+        sphere = hppfcl.Sphere(1.)
+        self.assertIsInstance(sphere, hppfcl.Sphere)
+        self.assertIsInstance(sphere, hppfcl.ShapeBase)
+        self.assertIsInstance(sphere, hppfcl.CollisionGeometry)
+        self.assertEqual(sphere.getNodeType(), hppfcl.NODE_TYPE.GEOM_SPHERE)
+        self.assertEqual(sphere.radius,1.)
+        sphere.radius = 2.
+        self.assertEqual(sphere.radius,2.)
+
+    def test_cylinder(self):
+        cylinder = hppfcl.Cylinder(1.,2.)
+        self.assertIsInstance(cylinder, hppfcl.Cylinder)
+        self.assertIsInstance(cylinder, hppfcl.ShapeBase)
+        self.assertIsInstance(cylinder, hppfcl.CollisionGeometry)
+        self.assertEqual(cylinder.getNodeType(), hppfcl.NODE_TYPE.GEOM_CYLINDER)
+        self.assertEqual(cylinder.radius,1.)
+        self.assertEqual(cylinder.lz,2.)
+
+    def test_cone(self):
+        cone = hppfcl.Cone(1.,2.)
+        self.assertIsInstance(cone, hppfcl.Cone)
+        self.assertIsInstance(cone, hppfcl.ShapeBase)
+        self.assertIsInstance(cone, hppfcl.CollisionGeometry)
+        self.assertEqual(cone.getNodeType(), hppfcl.NODE_TYPE.GEOM_CONE)
+        self.assertEqual(cone.radius,1.)
+        self.assertEqual(cone.lz,2.)
+        cone.radius = 3.
+        cone.lz = 4.
+        self.assertEqual(cone.radius,3.)
+        self.assertEqual(cone.lz,4.)
+
+if __name__ == '__main__':
+    unittest.main()
\ No newline at end of file
diff --git a/test/collision-bench.py b/test/scripts/collision-bench.py
similarity index 100%
rename from test/collision-bench.py
rename to test/scripts/collision-bench.py
diff --git a/test/collision.py b/test/scripts/collision.py
similarity index 100%
rename from test/collision.py
rename to test/scripts/collision.py
diff --git a/test/distance_lower_bound.py b/test/scripts/distance_lower_bound.py
similarity index 100%
rename from test/distance_lower_bound.py
rename to test/scripts/distance_lower_bound.py
diff --git a/test/geometric_shapes.py b/test/scripts/geometric_shapes.py
similarity index 100%
rename from test/geometric_shapes.py
rename to test/scripts/geometric_shapes.py
diff --git a/test/gjk.py b/test/scripts/gjk.py
similarity index 100%
rename from test/gjk.py
rename to test/scripts/gjk.py
diff --git a/test/obb.py b/test/scripts/obb.py
similarity index 100%
rename from test/obb.py
rename to test/scripts/obb.py
diff --git a/test/octree.py b/test/scripts/octree.py
similarity index 100%
rename from test/octree.py
rename to test/scripts/octree.py
diff --git a/travis_custom/custom_before_install_linux.sh b/travis_custom/custom_before_install_linux.sh
new file mode 100755
index 0000000000000000000000000000000000000000..37285b80c268fc4b86cb0b224e4a407bbf44d8bb
--- /dev/null
+++ b/travis_custom/custom_before_install_linux.sh
@@ -0,0 +1,11 @@
+# Add robotpkg
+sudo sh -c "echo \"deb [arch=amd64] http://robotpkg.openrobots.org/packages/debian/pub $(lsb_release -cs) robotpkg\" >> /etc/apt/sources.list"
+curl http://robotpkg.openrobots.org/packages/debian/robotpkg.key | sudo apt-key add -
+sudo apt-get update
+
+# install eigenpy
+sudo apt-get -qqy install robotpkg-py27-eigenpy
+
+# set environment variables
+export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/opt/openrobots/lib/pkgconfig"
+export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/openrobots/lib"
\ No newline at end of file
diff --git a/travis_custom/custom_before_install_osx.sh b/travis_custom/custom_before_install_osx.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8050eac617a6312a5ce8f50bd862cf3c1c33fdb9
--- /dev/null
+++ b/travis_custom/custom_before_install_osx.sh
@@ -0,0 +1,9 @@
+# Add gepetto tap
+brew tap gepetto/homebrew-gepetto
+
+# install eigenpy
+brew install eigenpy
+
+# set environment variables
+export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/opt/openrobots/lib/pkgconfig"
+export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/openrobots/lib"
\ No newline at end of file