diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed32bf2be2430972bc21d31c863faa90052414dc..7df290791872e58471154fa90866e14db87f4f10 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,3 +9,14 @@ add_subdirectory(pybind11)
 include_directories(${OPENMESH_INCLUDE_DIRS})
 pybind11_add_module(openmesh src/Bindings.cc src/InputOutput.cc src/Miscellaneous.cc)
 target_link_libraries(openmesh PRIVATE ${OPENMESH_LIBRARIES})
+
+enable_testing()
+add_test(
+	NAME discover_tests
+	COMMAND ${PYTHON_EXECUTABLE} -m unittest
+	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests
+)
+set_tests_properties(
+	discover_tests PROPERTIES
+	ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/Unittests/TestFiles/.gitignore b/tests/TestFiles/.gitignore
similarity index 100%
rename from Unittests/TestFiles/.gitignore
rename to tests/TestFiles/.gitignore
diff --git a/Unittests/TestFiles/cube-minimal-custom_props.ply b/tests/TestFiles/cube-minimal-custom_props.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-custom_props.ply
rename to tests/TestFiles/cube-minimal-custom_props.ply
diff --git a/Unittests/TestFiles/cube-minimal-degenerated.obj b/tests/TestFiles/cube-minimal-degenerated.obj
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-degenerated.obj
rename to tests/TestFiles/cube-minimal-degenerated.obj
diff --git a/Unittests/TestFiles/cube-minimal-extra-elements-binary.ply b/tests/TestFiles/cube-minimal-extra-elements-binary.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-extra-elements-binary.ply
rename to tests/TestFiles/cube-minimal-extra-elements-binary.ply
diff --git a/Unittests/TestFiles/cube-minimal-extra-elements.ply b/tests/TestFiles/cube-minimal-extra-elements.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-extra-elements.ply
rename to tests/TestFiles/cube-minimal-extra-elements.ply
diff --git a/Unittests/TestFiles/cube-minimal-normals.ply b/tests/TestFiles/cube-minimal-normals.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-normals.ply
rename to tests/TestFiles/cube-minimal-normals.ply
diff --git a/Unittests/TestFiles/cube-minimal-texCoords.obj b/tests/TestFiles/cube-minimal-texCoords.obj
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-texCoords.obj
rename to tests/TestFiles/cube-minimal-texCoords.obj
diff --git a/Unittests/TestFiles/cube-minimal-texCoords.om b/tests/TestFiles/cube-minimal-texCoords.om
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-texCoords.om
rename to tests/TestFiles/cube-minimal-texCoords.om
diff --git a/Unittests/TestFiles/cube-minimal-texCoords.ply b/tests/TestFiles/cube-minimal-texCoords.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-texCoords.ply
rename to tests/TestFiles/cube-minimal-texCoords.ply
diff --git a/Unittests/TestFiles/cube-minimal-texCoords3d.obj b/tests/TestFiles/cube-minimal-texCoords3d.obj
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-texCoords3d.obj
rename to tests/TestFiles/cube-minimal-texCoords3d.obj
diff --git a/Unittests/TestFiles/cube-minimal-vertex-colors-after-vertex-definition.obj b/tests/TestFiles/cube-minimal-vertex-colors-after-vertex-definition.obj
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-vertex-colors-after-vertex-definition.obj
rename to tests/TestFiles/cube-minimal-vertex-colors-after-vertex-definition.obj
diff --git a/Unittests/TestFiles/cube-minimal-vertex-colors-as-vc-lines.obj b/tests/TestFiles/cube-minimal-vertex-colors-as-vc-lines.obj
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-vertex-colors-as-vc-lines.obj
rename to tests/TestFiles/cube-minimal-vertex-colors-as-vc-lines.obj
diff --git a/Unittests/TestFiles/cube-minimal-vertexColors.om b/tests/TestFiles/cube-minimal-vertexColors.om
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-vertexColors.om
rename to tests/TestFiles/cube-minimal-vertexColors.om
diff --git a/Unittests/TestFiles/cube-minimal-vertexColors.ply b/tests/TestFiles/cube-minimal-vertexColors.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal-vertexColors.ply
rename to tests/TestFiles/cube-minimal-vertexColors.ply
diff --git a/Unittests/TestFiles/cube-minimal.obj b/tests/TestFiles/cube-minimal.obj
similarity index 100%
rename from Unittests/TestFiles/cube-minimal.obj
rename to tests/TestFiles/cube-minimal.obj
diff --git a/Unittests/TestFiles/cube-minimal.om b/tests/TestFiles/cube-minimal.om
similarity index 100%
rename from Unittests/TestFiles/cube-minimal.om
rename to tests/TestFiles/cube-minimal.om
diff --git a/Unittests/TestFiles/cube-minimal.ply b/tests/TestFiles/cube-minimal.ply
similarity index 100%
rename from Unittests/TestFiles/cube-minimal.ply
rename to tests/TestFiles/cube-minimal.ply
diff --git a/Unittests/TestFiles/cube1.off b/tests/TestFiles/cube1.off
similarity index 100%
rename from Unittests/TestFiles/cube1.off
rename to tests/TestFiles/cube1.off
diff --git a/Unittests/TestFiles/cube1.pm b/tests/TestFiles/cube1.pm
similarity index 100%
rename from Unittests/TestFiles/cube1.pm
rename to tests/TestFiles/cube1.pm
diff --git a/Unittests/TestFiles/cube1.stl b/tests/TestFiles/cube1.stl
similarity index 100%
rename from Unittests/TestFiles/cube1.stl
rename to tests/TestFiles/cube1.stl
diff --git a/Unittests/TestFiles/cube1Binary.stl b/tests/TestFiles/cube1Binary.stl
similarity index 100%
rename from Unittests/TestFiles/cube1Binary.stl
rename to tests/TestFiles/cube1Binary.stl
diff --git a/Unittests/TestFiles/cube1_customProps.om b/tests/TestFiles/cube1_customProps.om
similarity index 100%
rename from Unittests/TestFiles/cube1_customProps.om
rename to tests/TestFiles/cube1_customProps.om
diff --git a/Unittests/TestFiles/meshlab.ply b/tests/TestFiles/meshlab.ply
similarity index 100%
rename from Unittests/TestFiles/meshlab.ply
rename to tests/TestFiles/meshlab.ply
diff --git a/Unittests/TestFiles/pointCloudBadEncoding.ply b/tests/TestFiles/pointCloudBadEncoding.ply
similarity index 100%
rename from Unittests/TestFiles/pointCloudBadEncoding.ply
rename to tests/TestFiles/pointCloudBadEncoding.ply
diff --git a/Unittests/TestFiles/pointCloudGoodEncoding.ply b/tests/TestFiles/pointCloudGoodEncoding.ply
similarity index 100%
rename from Unittests/TestFiles/pointCloudGoodEncoding.ply
rename to tests/TestFiles/pointCloudGoodEncoding.ply
diff --git a/Unittests/TestFiles/square_material.mtl b/tests/TestFiles/square_material.mtl
similarity index 100%
rename from Unittests/TestFiles/square_material.mtl
rename to tests/TestFiles/square_material.mtl
diff --git a/Unittests/TestFiles/square_material.obj b/tests/TestFiles/square_material.obj
similarity index 100%
rename from Unittests/TestFiles/square_material.obj
rename to tests/TestFiles/square_material.obj
diff --git a/Unittests/TestFiles/square_material_texture.mtl b/tests/TestFiles/square_material_texture.mtl
similarity index 100%
rename from Unittests/TestFiles/square_material_texture.mtl
rename to tests/TestFiles/square_material_texture.mtl
diff --git a/Unittests/TestFiles/square_material_texture.obj b/tests/TestFiles/square_material_texture.obj
similarity index 100%
rename from Unittests/TestFiles/square_material_texture.obj
rename to tests/TestFiles/square_material_texture.obj
diff --git a/Unittests/test_add_face.py b/tests/test_add_face.py
similarity index 100%
rename from Unittests/test_add_face.py
rename to tests/test_add_face.py
diff --git a/Unittests/test_boundary.py b/tests/test_boundary.py
similarity index 100%
rename from Unittests/test_boundary.py
rename to tests/test_boundary.py
diff --git a/Unittests/test_delete_face.py b/tests/test_delete_face.py
similarity index 100%
rename from Unittests/test_delete_face.py
rename to tests/test_delete_face.py
diff --git a/Unittests/test_property.py b/tests/test_property.py
similarity index 100%
rename from Unittests/test_property.py
rename to tests/test_property.py
diff --git a/Unittests/test_python.py b/tests/test_python.py
similarity index 100%
rename from Unittests/test_python.py
rename to tests/test_python.py
diff --git a/Unittests/test_read_write_obj.py b/tests/test_read_write_obj.py
similarity index 100%
rename from Unittests/test_read_write_obj.py
rename to tests/test_read_write_obj.py
diff --git a/Unittests/test_read_write_off.py b/tests/test_read_write_off.py
similarity index 100%
rename from Unittests/test_read_write_off.py
rename to tests/test_read_write_off.py
diff --git a/Unittests/test_read_write_om.py b/tests/test_read_write_om.py
similarity index 100%
rename from Unittests/test_read_write_om.py
rename to tests/test_read_write_om.py
diff --git a/Unittests/test_read_write_ply.py b/tests/test_read_write_ply.py
similarity index 100%
rename from Unittests/test_read_write_ply.py
rename to tests/test_read_write_ply.py
diff --git a/Unittests/test_read_write_stl.py b/tests/test_read_write_stl.py
similarity index 100%
rename from Unittests/test_read_write_stl.py
rename to tests/test_read_write_stl.py
diff --git a/Unittests/test_split_copy.py b/tests/test_split_copy.py
similarity index 100%
rename from Unittests/test_split_copy.py
rename to tests/test_split_copy.py
diff --git a/Unittests/test_trimesh_circulator_current_halfedge_handle_replacement.py b/tests/test_trimesh_circulator_current_halfedge_handle_replacement.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_current_halfedge_handle_replacement.py
rename to tests/test_trimesh_circulator_current_halfedge_handle_replacement.py
diff --git a/Unittests/test_trimesh_circulator_face_edge.py b/tests/test_trimesh_circulator_face_edge.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_face_edge.py
rename to tests/test_trimesh_circulator_face_edge.py
diff --git a/Unittests/test_trimesh_circulator_face_face.py b/tests/test_trimesh_circulator_face_face.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_face_face.py
rename to tests/test_trimesh_circulator_face_face.py
diff --git a/Unittests/test_trimesh_circulator_face_halfedge.py b/tests/test_trimesh_circulator_face_halfedge.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_face_halfedge.py
rename to tests/test_trimesh_circulator_face_halfedge.py
diff --git a/Unittests/test_trimesh_circulator_face_vertex.py b/tests/test_trimesh_circulator_face_vertex.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_face_vertex.py
rename to tests/test_trimesh_circulator_face_vertex.py
diff --git a/Unittests/test_trimesh_circulator_halfedge_loop.py b/tests/test_trimesh_circulator_halfedge_loop.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_halfedge_loop.py
rename to tests/test_trimesh_circulator_halfedge_loop.py
diff --git a/Unittests/test_trimesh_circulator_vertex_edge.py b/tests/test_trimesh_circulator_vertex_edge.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_vertex_edge.py
rename to tests/test_trimesh_circulator_vertex_edge.py
diff --git a/Unittests/test_trimesh_circulator_vertex_face.py b/tests/test_trimesh_circulator_vertex_face.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_vertex_face.py
rename to tests/test_trimesh_circulator_vertex_face.py
diff --git a/Unittests/test_trimesh_circulator_vertex_ihalfedge.py b/tests/test_trimesh_circulator_vertex_ihalfedge.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_vertex_ihalfedge.py
rename to tests/test_trimesh_circulator_vertex_ihalfedge.py
diff --git a/Unittests/test_trimesh_circulator_vertex_ohalfedge.py b/tests/test_trimesh_circulator_vertex_ohalfedge.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_vertex_ohalfedge.py
rename to tests/test_trimesh_circulator_vertex_ohalfedge.py
diff --git a/Unittests/test_trimesh_circulator_vertex_vertex.py b/tests/test_trimesh_circulator_vertex_vertex.py
similarity index 100%
rename from Unittests/test_trimesh_circulator_vertex_vertex.py
rename to tests/test_trimesh_circulator_vertex_vertex.py
diff --git a/Unittests/test_trimesh_collapse.py b/tests/test_trimesh_collapse.py
similarity index 100%
rename from Unittests/test_trimesh_collapse.py
rename to tests/test_trimesh_collapse.py
diff --git a/Unittests/test_trimesh_garbage_collection.py b/tests/test_trimesh_garbage_collection.py
similarity index 100%
rename from Unittests/test_trimesh_garbage_collection.py
rename to tests/test_trimesh_garbage_collection.py
diff --git a/Unittests/test_trimesh_iterators.py b/tests/test_trimesh_iterators.py
similarity index 100%
rename from Unittests/test_trimesh_iterators.py
rename to tests/test_trimesh_iterators.py
diff --git a/Unittests/test_trimesh_normal_calculations.py b/tests/test_trimesh_normal_calculations.py
similarity index 100%
rename from Unittests/test_trimesh_normal_calculations.py
rename to tests/test_trimesh_normal_calculations.py
diff --git a/Unittests/test_trimesh_others.py b/tests/test_trimesh_others.py
similarity index 100%
rename from Unittests/test_trimesh_others.py
rename to tests/test_trimesh_others.py
diff --git a/Unittests/test_vector_type.py b/tests/test_vector_type.py
similarity index 100%
rename from Unittests/test_vector_type.py
rename to tests/test_vector_type.py