diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 48baa235626ffec7e4eb963d01dc0a136e186f26..b3333652b9f5e2f245a29dcaf37c199c5d783bdb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -195,7 +195,7 @@ test:windows_nightly:msvc++14.1:
 conan:linux:clang:
   stage: conan
   except:
-    - shedules
+    - schedules
   tags:
     - CentOS
     - opengl
@@ -214,7 +214,7 @@ conan:linux:clang:
 cmake:linux:clang:
   stage: cmake
   except:
-    - shedules
+    - schedules
   tags:
     - CentOS
     - opengl
@@ -289,7 +289,7 @@ clear:linux_nightly:clang:
 conan:linux_nightly:clang:
   stage: conan
   only:
-    - shedules
+    - schedules
   tags:
     - nightly
     - clang
@@ -309,7 +309,7 @@ conan:linux_nightly:clang:
 cmake:linux_nightly:clang:
   stage: cmake
   only:
-    - shedules
+    - schedules
   tags:
     - nightly
     - clang
diff --git a/README.md b/README.md
index f11bf1102f35d13fe0d395b182dd5e61a7efa8c9..7ab2218c7d663645340f5f5a9ed249da8d4e75be 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
 # Project Phoenix
 
-**Master:** [![build status](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/badges/master/build.svg)](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/commits/master)
+**Stable:** [![build status](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/badges/stable/build.svg)](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/commits/stable)
  
-**Develop:** [![build status](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/badges/develop/build.svg)](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/commits/develop)
+**Master:** [![build status](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/badges/master/build.svg)](https://devhub.vr.rwth-aachen.de/VR-Group/Project_Phoenix/commits/master)
 
 *Project Phoenix* is Copyright (c) 2017-2018 RWTH Aachen University, Germany,
 Virtual Reality & Immersive Visualization Group.
diff --git a/cmake/Testing.cmake b/cmake/Testing.cmake
index 36cf0f171ae76dfa442e590a7ef9c2c4beb462b2..47ea597015eee6a1577dfdde1cb4cff0c98e69d3 100644
--- a/cmake/Testing.cmake
+++ b/cmake/Testing.cmake
@@ -28,12 +28,122 @@ include(WarningLevels)
 conan_or_find_package(catch REQUIRED)
 conan_or_find_package(trompeloeil REQUIRED)
 
+define_property(TARGET
+  PROPERTY testing__removes_libraries
+  BRIEF_DOCS "Libraries to be removed for mocking"
+  FULL_DOCS "Libraries to be removed for mocking")
+define_property(TARGET
+  PROPERTY testing__adds_libraries
+  BRIEF_DOCS "Libraries to be added for mocking"
+  FULL_DOCS "Libraries to be added for mocking")
+
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+set_property(GLOBAL PROPERTY TESTING__AVAILABLE_TESTS "")
+
+set(IS_BUILD_SERVER
+  FALSE CACHE BOOL
+  "Is this the build server? So we, e.g., simulate user input for tests requiring it."
+  )
+
 
-set_property(GLOBAL PROPERTY ADDED_TESTS "")
+function(CREATE_TEST_MAIN)
+  testing__add_library_(NAME test_main ${ARGV})
+endfunction()
+
+
+function(CREATE_MOCK_MAIN)
+  testing__add_library_(NAME mock_main ${ARGV})
+endfunction()
+
+
+function(TESTING__ADD_LIBRARY_)
+  set(options)
+  set(oneValueArgs NAME)
+  set(multiValueArgs SOURCES HEADERS INCLUDE_DIRECTORIES LIBRARIES )
+  cmake_parse_arguments(TESTING__ADD_LIBRARY_
+    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+  add_library(${TESTING__ADD_LIBRARY__NAME}
+    ${TESTING__ADD_LIBRARY__SOURCES}
+    ${TESTING__ADD_LIBRARY__HEADERS}
+    )
+  target_include_directories(${TESTING__ADD_LIBRARY__NAME}
+    PUBLIC ${TESTING__ADD_LIBRARY__INCLUDE_DIRECTORIES}
+    )
+  target_link_libraries(${TESTING__ADD_LIBRARY__NAME}
+    ${TESTING__ADD_LIBRARY__LIBRARIES}
+    )
+  set_property(TARGET ${TESTING__ADD_LIBRARY__NAME} PROPERTY POSITION_INDEPENDENT_CODE ON)
+endfunction()
+
+
+function(ADD_TESTS)
+  set(options )
+  set(oneValueArgs NAME)
+  set(multiValueArgs
+    SOURCES HEADERS INCLUDE_DIRECTORIES LIBRARIES PATH_TO_ADD)
+  cmake_parse_arguments(ADD_TESTS_
+    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+  foreach(TEST_SOURCE_FILE ${ADD_TESTS__SOURCES})
+    add_single_test(
+      NAME ${TEST_NAME}
+      SOURCE ${TEST_SOURCE_FILE}
+      INCLUDE_DIRECTORIES ${ADD_TESTS__INCLUDE_DIRECTORIES}
+      LIBRARIES ${ADD_TESTS__LIBRARIES}
+      PATH_TO_ADD ${ADD_TESTS__PATH_TO_ADD}
+      )
+  endforeach()
+endfunction()
+
+
+function(ADD_SINGLE_TEST)
+  set(options )
+  set(oneValueArgs)
+  set(multiValueArgs SOURCE INCLUDE_DIRECTORIES LIBRARIES PATH_TO_ADD)
+  cmake_parse_arguments(ADD_SINGLE_TEST_
+    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
+  get_filename_component(
+    TEST_NAME
+    ${ADD_SINGLE_TEST__SOURCE} NAME_WE)
 
-function(CONFIGURE_MSVC_USERFILE TARGET_NAME PATH_TO_ADD)
+  add_executable(${TEST_NAME}
+    ${ADD_SINGLE_TEST__SOURCE}
+    )
+  target_include_directories(${TEST_NAME}
+    PRIVATE ${ADD_SINGLE_TEST__INCLUDE_DIRECTORIES}
+    )
+  target_link_libraries(${TEST_NAME}
+    ${ADD_SINGLE_TEST__LIBRARIES}
+    ${CONAN_OR_CMAKE_catch}
+    test_main mock_main
+    )
+  set_warning_levels_RWTH(${TEST_NAME})
+  if(IS_BUILD_SERVER)
+    target_compile_definitions(${TEST_NAME} PUBLIC -DIS_BUILD_SERVER)
+  endif()
+  set_property(TARGET ${TEST_NAME}
+    PROPERTY FOLDER "Tests")
+  source_group("Source Files"
+    FILES ${ADD_SINGLE_TEST__SOURCE})
+
+  if(ADD_SINGLE_TEST__PATH_TO_ADD AND WIN32 AND MSVC)
+    CONFIGURE_MSVC_USERFILE_(${TEST_NAME}
+      ${ADD_SINGLE_TEST__PATH_TO_ADD})
+  endif()
+  
+  add_test(NAME ${TEST_NAME}
+    COMMAND ${TEST_NAME}
+    )
+  testing__set_timeout_(${TEST_NAME})
+
+  set_property(GLOBAL APPEND PROPERTY
+    TESTING__AVAILABLE_TESTS "${TEST_NAME}")  
+endfunction()
+
+
+function(CONFIGURE_MSVC_USERFILE_ TARGET_NAME PATH_TO_ADD)
   file(TO_NATIVE_PATH "${PATH_TO_ADD}/Release" _DLL_PATH_RELEASE)
   file(TO_NATIVE_PATH "${PATH_TO_ADD}/Debug" _DLL_PATH_DEBUG)
   set(SOURCE_USER_FILE
@@ -43,132 +153,157 @@ function(CONFIGURE_MSVC_USERFILE TARGET_NAME PATH_TO_ADD)
   configure_file(${SOURCE_USER_FILE} ${DESTINATION_USER_FILE} @ONLY)
 endfunction()
 
-function(ADD_TEST_TARGET_INTERNAL_
-    NAME SOURCES HEADERS INCLUDE_DIRECTORIES LINK_LIBRARIES PATH_TO_ADD)
-  add_executable(${NAME} ${SOURCES} ${HEADERS})
-  target_include_directories(${NAME} PRIVATE ${INCLUDE_DIRECTORIES})
-  target_link_libraries(${NAME} ${LINK_LIBRARIES})
-  target_link_libraries(${NAME} ${CONAN_OR_CMAKE_catch})
-   
-  if(WIN32 AND MSVC)
-    CONFIGURE_MSVC_USERFILE(${NAME} ${PATH_TO_ADD})
-  endif()
-endfunction()
 
-function(ADD_TEST_CATCH_INTERNAL_ 
-    NAME SOURCES HEADERS)
-  
-  add_test(NAME ${NAME} COMMAND ${NAME})
-  if(NOT ${NAME} MATCHES "integration")
-    set_tests_properties(${NAME} PROPERTIES TIMEOUT 10.0)
+function(TESTING__SET_TIMEOUT_ TARGET)
+  if(NOT ${TARGET} MATCHES "integration")
+    set_tests_properties(${TARGET} PROPERTIES TIMEOUT 10.0)
   else()
-    set_tests_properties(${NAME} PROPERTIES TIMEOUT 120.0)
+    set_tests_properties(${TARGET} PROPERTIES TIMEOUT 120.0)
   endif()
-  set_warning_levels_RWTH(${NAME})
+endfunction()
 
-  set_property(TARGET ${NAME} PROPERTY FOLDER "Tests")
-  source_group("Source Files" FILES ${SOURCES} ${HEADERS})
-  
-  set_property(GLOBAL APPEND PROPERTY ADDED_TESTS "${NAME}")
-  
-  if(IS_BUILD_SERVER)
-    target_compile_definitions(${NAME} PUBLIC -DIS_BUILD_SERVER)
-  endif()
+
+function(ADD_MOCK)
+  set(options )
+  set(oneValueArgs NAME)
+  set(multiValueArgs
+    SOURCES
+    HEADERS
+    INCLUDE_DIRECTORIES
+    INCLUDE_DIRECTORIES_OF
+    COMPILE_OPTIONS
+    REMOVES_LIBRARIES
+    ADDS_LIBRARIES
+  )
+  cmake_parse_arguments(ADD_MOCK_
+    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+  string(TOUPPER ${ADD_MOCK__NAME} ADD_MOCK__NAME_UPPER)
+  string(TOLOWER ${ADD_MOCK__NAME} ADD_MOCK__NAME_LOWER)
   
-endfunction()
+  add_library(${ADD_MOCK__NAME} SHARED
+    ${ADD_MOCK__SOURCES}
+    ${ADD_MOCK__HEADERS}
+    )
+  target_link_libraries(${ADD_MOCK__NAME}
+    ${CONAN_OR_CMAKE_trompeloeil}
+    mock_main test_main
+    )
+  foreach(CURRENT_TARGET ${ADD_MOCK__INCLUDE_DIRECTORIES_OF})
+    get_target_property(CURRENT_INCLUCE_DIRECTORIES
+      ${CURRENT_TARGET} INTERFACE_INCLUDE_DIRECTORIES)
+    if (CURRENT_INCLUCE_DIRECTORIES)
+      target_include_directories(${ADD_MOCK__NAME}
+	    PUBLIC ${CURRENT_INCLUCE_DIRECTORIES}
+	  )
+    endif()
+  endforeach()
+  target_include_directories(${ADD_MOCK__NAME}
+    PUBLIC ${ADD_MOCK__INCLUDE_DIRECTORIES}
+    )
+  target_compile_definitions(${ADD_MOCK__NAME}
+    PRIVATE ${ADD_MOCK__NAME_UPPER}_BUILD
+    )
+  target_compile_options(${ADD_MOCK__NAME}
+    PUBLIC ${ADD_MOCK__COMPILE_OPTIONS}
+    )
 
-function(ADD_TEST_INTERNAL_ 
-    NAME SOURCES HEADERS INCLUDE_DIRECTORIES LINK_LIBRARIES PATH_TO_ADD)
-  ADD_TEST_TARGET_INTERNAL_("${NAME}" "${SOURCES}" "${HEADERS}" "${INCLUDE_DIRECTORIES}" "${LINK_LIBRARIES}" "${PATH_TO_ADD}")
-  ADD_TEST_CATCH_INTERNAL_("${NAME}" "${SOURCES}" "${HEADERS}")
-endfunction()
+  set_property(TARGET ${ADD_MOCK__NAME} PROPERTY FOLDER "Tests/Mocks")
 
+  set_target_properties(${ADD_MOCK__NAME}
+    PROPERTIES testing__removes_libraries "${ADD_MOCK__REMOVES_LIBRARIES}")
+  set_target_properties(${ADD_MOCK__NAME}
+    PROPERTIES testing__adds_libraries "${ADD_MOCK__ADDS_LIBRARIES}")
 
+  generate_export_header(${ADD_MOCK__NAME}
+    EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/mocks/${ADD_MOCK__NAME_LOWER}_export.hpp
+    )
+  set_warning_levels_rwth(${ADD_MOCK__NAME})
+endfunction()
 
 
-function(CREATE_CATCH_MAIN_INTERNAL_
-    NAME SOURCE INCLUDE_DIRECTORIES)
-  add_library(${NAME} ${SOURCE})
-  target_include_directories(${NAME} PRIVATE ${INCLUDE_DIRECTORIES})
-  target_link_libraries(${NAME} ${CONAN_OR_CMAKE_catch} ${CONAN_OR_CMAKE_trompeloeil})
-  set_property(TARGET ${NAME} PROPERTY FOLDER "Tests")
-  source_group("Source Files" FILES ${SOURCE})
+function(AUTOREMOVE_MOCKED_TEST_SOURCE_FROM)
+  set_property(GLOBAL PROPERTY TESTING__SOURCES__AUTOREMOVE_MOCKED ${ARGN})
 endfunction()
 
+function(GET_UNMOCKED_TEST_SOURCES test_list)
+  get_property(TEST_SOURCES_LIST
+    GLOBAL PROPERTY TESTING__SOURCES__AUTOREMOVE_MOCKED) 
+  set(${test_list} ${TEST_SOURCES_LIST} PARENT_SCOPE)
+endfunction()
 
-function(ADD_TEST_CATCH)
-  # parse arguments
+function(add_mocked_test cpp_file)
   set(options )
-  set(oneValueArgs NAME CATCH_MAIN)
-  set(multiValueArgs
-    SOURCES HEADERS INCLUDE_DIRECTORIES LINK_LIBRARIES PATH_TO_ADD)
-  cmake_parse_arguments(ADD_TEST_CATCH
+  set(oneValueArgs )
+  set(multiValueArgs LIBRARIES MOCKING_LIBRARIES_OF MOCKS)
+  cmake_parse_arguments(ADD_MOCKED_TEST
     "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 
-  create_catch_main_internal_("${ADD_TEST_CATCH_NAME}_catch_main"
-    ${ADD_TEST_CATCH_CATCH_MAIN}
-    ${ADD_TEST_CATCH_INCLUDE_DIRECTORIES}
-  )
-
-  # remove catch_main file from sources
-  file(GLOB ADD_TEST_CATCH_CATCH_MAIN_ABSOLUTE ${ADD_TEST_CATCH_CATCH_MAIN})
-  list(REMOVE_ITEM ADD_TEST_CATCH_SOURCES ${ADD_TEST_CATCH_CATCH_MAIN_ABSOLUTE})
-
-  # add test for each test source file
-  foreach(TEST_SOURCE_FILE ${ADD_TEST_CATCH_SOURCES})
-    get_filename_component(TEST_NAME ${TEST_SOURCE_FILE} NAME_WE)
-    ADD_TEST_INTERNAL_("${TEST_NAME}"
-      "${TEST_SOURCE_FILE}"
-      ""
-      "${ADD_TEST_CATCH_INCLUDE_DIRECTORIES}"
-      "${ADD_TEST_CATCH_LINK_LIBRARIES};${ADD_TEST_CATCH_NAME}_catch_main"
-      "${ADD_TEST_CATCH_PATH_TO_ADD}"
+ 
+  get_property(TEST_SOURCES_LIST
+    GLOBAL PROPERTY TESTING__SOURCES__AUTOREMOVE_MOCKED) 
+  list(REMOVE_ITEM TEST_SOURCES_LIST
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/${cpp_file}.cpp)
+  set_property(GLOBAL PROPERTY TESTING__SOURCES__AUTOREMOVE_MOCKED ${TEST_SOURCES_LIST})
+  
+  set(test_sources src/${cpp_file}.cpp)
+  add_single_test(
+    SOURCE ${test_sources}
     )
-  endforeach()
-endfunction()
+  add_dependencies(${cpp_file} ${ADD_MOCKED_TEST_LIBRARIES})
+
+  set(LINK_LIBRARIES )
+  foreach(CURR_TARGET ${ADD_MOCKED_TEST_LIBRARIES})
+    get_target_property(CURR_LINK_LIBRARIES ${CURR_TARGET} LINK_LIBRARIES)
+    list(APPEND LINK_LIBRARIES ${CURR_LINK_LIBRARIES})
 
-macro(EXTRACT_UNIT_AND_INTEGRATION_TEST_TARGETS)
-  get_property(added_tests GLOBAL PROPERTY ADDED_TESTS)
-  foreach(filename ${added_tests})
-  	if(${filename} MATCHES "integration_test")
-  	  message(STATUS "Integration Test: ${filename}")
-  	  set(INTEGRATION_TEST_TARGETS ${INTEGRATION_TEST_TARGETS} ${filename})
-  	else()
-  	  message(STATUS "Unit Test: ${filename}")
-  	  set(UNIT_TEST_TARGETS ${UNIT_TEST_TARGETS} ${filename})
-  	endif()
+    target_link_libraries(${cpp_file} $<TARGET_FILE:${CURR_TARGET}>)
+	
+	get_target_property(CURR_INCLUDE_DIRECTORIES
+      ${CURR_TARGET} INCLUDE_DIRECTORIES)
+    target_include_directories(${cpp_file} PRIVATE ${CURR_INCLUDE_DIRECTORIES})
+  endforeach()
+  list(REMOVE_DUPLICATES LINK_LIBRARIES)
+  #the libraries themselves must not be in LINK_LIBRARIES
+  foreach(CURR_TARGET ${ADD_MOCKED_TEST_LIBRARIES})
+    list(REMOVE_ITEM LINK_LIBRARIES ${CURR_TARGET})
   endforeach()
-endmacro()
 
-macro(ADD_TEST_SUITE)
-  set(options)
-  set(oneValueArgs NAME TEST_REGEX)
-  set(multiValueArgs DEPEND_ON_TARGETS)
-  cmake_parse_arguments(ADD_TEST_SUITE
-    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-  #we have to escape the " for visual studio)
-  add_custom_target(${ADD_TEST_SUITE_NAME} COMMAND ctest --tests-regex \"${ADD_TEST_SUITE_TEST_REGEX}\" -C $<CONFIG>)
-   # This comment just ends the escaped signs, for VS highlighting "
-  if(ADD_TEST_SUITE_DEPEND_ON_TARGETS)
-    add_dependencies(${ADD_TEST_SUITE_NAME} ${ADD_TEST_SUITE_DEPEND_ON_TARGETS})
-  endif()
-  set_property(TARGET ${ADD_TEST_SUITE_NAME} PROPERTY FOLDER "_Test-Suites_")
-endmacro()
+  foreach(MOCK ${ADD_MOCKED_TEST_MOCKS})
+    get_target_property(LIBRARIES_TO_BE_REMOVED ${MOCK} testing__removes_libraries)
+    foreach(LIBRARY_TO_BE_REMOVED ${LIBRARIES_TO_BE_REMOVED})
+      list(REMOVE_ITEM LINK_LIBRARIES ${LIBRARY_TO_BE_REMOVED})
+    endforeach()
+    
+    get_target_property(LIBRARIES_TO_BE_ADDED ${MOCK} testing__adds_libraries)
+    foreach(LIBRARY_TO_BE_ADDED ${LIBRARIES_TO_BE_ADDED})
+      list(APPEND LINK_LIBRARIES ${LIBRARY_TO_BE_ADDED})
+    endforeach()
 
+    target_link_libraries(${cpp_file} ${MOCK})
+  endforeach()
+  
+  target_link_libraries(${cpp_file}
+    ${CONAN_OR_CMAKE_trompeloeil}
+    ${CONAN_OR_CMAKE_catch}
+    ${LINK_LIBRARIES}
+  )
+endfunction()
+#-------------------------------------------------------------------------------
 
 
 function(CREATE_TEST_SUITES)
-	EXTRACT_UNIT_AND_INTEGRATION_TEST_TARGETS()
+	testing__extract_unit_and_integration_test_targets_()
 
 	ADD_TEST_SUITE(
 	  NAME "Unit-Test-Suite"
 	  TEST_REGEX "^test"
-	  DEPEND_ON_TARGETS ${UNIT_TEST_TARGETS})
+	  DEPEND_ON_TARGETS ${TESTING__UNIT_TESTS})
 
 	ADD_TEST_SUITE(
 	  NAME "Integration-Test-Suite"
 	  TEST_REGEX "^integration"
-	  DEPEND_ON_TARGETS ${INTEGRATION_TEST_TARGETS})
+	  DEPEND_ON_TARGETS ${TESTING__INTEGRATION_TESTS})
 	
 	ADD_TEST_SUITE(
 	  NAME "Cpplint-Test-Suite"
@@ -178,3 +313,36 @@ function(CREATE_TEST_SUITES)
 	  NAME "Cppcheck-Test-Suite"
 	  TEST_REGEX "cppcheck")
 endfunction()
+
+
+function(ADD_TEST_SUITE)
+  set(options)
+  set(oneValueArgs NAME TEST_REGEX)
+  set(multiValueArgs DEPEND_ON_TARGETS)
+  cmake_parse_arguments(ADD_TEST_SUITE
+    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+  
+  #we have to escape the " for visual studio)
+  add_custom_target(${ADD_TEST_SUITE_NAME} COMMAND ctest --tests-regex \"${ADD_TEST_SUITE_TEST_REGEX}\" -C $<CONFIG>)
+   # This comment just ends the escaped signs, for VS highlighting "
+  if(ADD_TEST_SUITE_DEPEND_ON_TARGETS)
+    add_dependencies(${ADD_TEST_SUITE_NAME} ${ADD_TEST_SUITE_DEPEND_ON_TARGETS})
+  endif()
+  set_property(TARGET ${ADD_TEST_SUITE_NAME} PROPERTY FOLDER "_Test-Suites_")
+endfunction()
+
+
+function(TESTING__EXTRACT_UNIT_AND_INTEGRATION_TEST_TARGETS_)
+  set(TESTING__INTEGRATION_TESTS )
+  set(TESTING__UNIT_TESTS )
+
+  get_property(TESTING__AVAILABLE_TESTS GLOBAL PROPERTY TESTING__AVAILABLE_TESTS)
+  foreach(CURRENT_TEST ${TESTING__AVAILABLE_TESTS})
+    if(${CURRENT_TEST} MATCHES "integration_test")
+      list(APPEND TESTING__INTEGRATION_TESTS ${CURRENT_TEST})
+    else()
+      list(APPEND TESTING__UNIT_TESTS ${CURRENT_TEST})
+    endif()
+  endforeach()
+endfunction()
+
diff --git a/cmake/WarningLevels.cmake b/cmake/WarningLevels.cmake
index 56a8e549bb1067c10917f306c3ef5e7b68d45396..cfe1929d1499691c9051370dd51170a008947a62 100644
--- a/cmake/WarningLevels.cmake
+++ b/cmake/WarningLevels.cmake
@@ -34,6 +34,7 @@ set(WARNING_LEVELS_RWTH_CLANG
   -Wno-weak-vtables
   -Wno-exit-time-destructors
   -Wno-global-constructors
+  -Wno-padded
 )
 
 set(WARNING_LEVELS_RWTH_GCC
diff --git a/cmake/cpplint.cmake b/cmake/cpplint.cmake
index 9342399d3f15c119b3fd1fddeb4fe741fa8dc999..30f125900088e662e140b531bbd9804c3b373ec8 100644
--- a/cmake/cpplint.cmake
+++ b/cmake/cpplint.cmake
@@ -77,5 +77,5 @@ function(ADD_TEST_CPPLINT)
     COMMAND ${PYTHON_EXECUTABLE} ${CPPLINT_COMMAND} ${CPPLINT_OUTPUT} ${CPPLINT_ARGS}
     ${ADD_TEST_CPPLINT_UNPARSED_ARGUMENTS}
     )
-  set_tests_properties(${ADD_TEST_CPPLINT_NAME} PROPERTIES TIMEOUT 20.0)
+  set_tests_properties(${ADD_TEST_CPPLINT_NAME} PROPERTIES TIMEOUT 100.0)
 endfunction()
diff --git a/cmake/suppress_warnings.hpp.in b/cmake/suppress_warnings.hpp.in
index 5a9ae8a7c8ad2d395ce944f1a859c6d09c11b93c..ddd2a44b761befa44ce4e8096990ea918503ce1b 100644
--- a/cmake/suppress_warnings.hpp.in
+++ b/cmake/suppress_warnings.hpp.in
@@ -40,10 +40,8 @@
   _Pragma("clang diagnostic ignored \"-Wsign-conversion\"")               \
   _Pragma("clang diagnostic ignored \"-Wnewline-eof\"")                   \
   _Pragma("clang diagnostic ignored \"-Wnon-virtual-dtor\"")              \
+  _Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"") \
   _Pragma("clang diagnostic ignored \"-Wextra-semi\"")
-#define SUPPRESS_WARNINGS_BEGIN_PADDED \
-  _Pragma("clang diagnostic push")                                        \
-  _Pragma("clang diagnostic ignored \"-Wpadded\"")
 #define SUPPRESS_WARNINGS_BEGIN_MISSING_DECLARATIONS                      \
   _Pragma("clang diagnostic push")                                        \
   _Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"")
@@ -51,7 +49,6 @@
 
 #elif defined _MSC_VER
 #define SUPPRESS_WARNINGS_BEGIN __pragma(warning(push, 0));
-#define SUPPRESS_WARNINGS_BEGIN_PADDED  __pragma(warning(push));
 #define SUPPRESS_WARNINGS_BEGIN_MISSING_DECLARATIONS  __pragma(warning(push));
 #define SUPPRESS_WARNINGS_END __pragma(warning(pop));
 
@@ -69,9 +66,6 @@
   _Pragma("GCC diagnostic ignored \"-Wextra\"")                           \
   _Pragma("GCC diagnostic ignored \"-Wmissing-declarations\"")            \
   _Pragma("GCC diagnostic ignored \"-Wpadded\"")
-#define SUPPRESS_WARNINGS_BEGIN_PADDED                                    \
-  _Pragma("GCC diagnostic push")                                          \
-  _Pragma("GCC diagnostic ignored \"-Wpadded\"")
 #define SUPPRESS_WARNINGS_BEGIN_MISSING_DECLARATIONS                      \
   _Pragma("GCC diagnostic push")                                          \
   _Pragma("GCC diagnostic ignored \"-Wmissing-declarations\"")
diff --git a/conanfile.py b/conanfile.py
index f063bcf54491b189de020b23e3152f7efb784bd3..ab6e629068d80040043338742031e58924b24a6a 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -67,6 +67,6 @@ class ProjectPhoenix(ConanFile):
        self.copy("*.dll", dst="demos/combustion_demo/Debug", src="bin")
        self.copy("*.dll", dst="demos/combustion_demo/Release", src="bin")
        self.copy("*.so", dst="lib", src="lib")
-       self.copy("*.so*", dst="lib", src="lib")
+       self.copy("*.so.*", dst="lib", src="lib")
        self.copy("*.dylib", dst="lib", src="lib")
        self.copy("*.dylib", dst="tests", src="lib")
diff --git a/demos/viewer/src/navigation_behavior.hpp b/demos/viewer/src/navigation_behavior.hpp
index ac2e06c9ef98424e746f42a41d3880e5079781da..aee9accca37a44597cd536ae96edbcb5d6471ab4 100644
--- a/demos/viewer/src/navigation_behavior.hpp
+++ b/demos/viewer/src/navigation_behavior.hpp
@@ -31,7 +31,7 @@ class NavigationBehavior : public phx::Behavior {
   explicit NavigationBehavior(phx::DisplaySystemOpenVR* display_system_openvr);
   NavigationBehavior(const NavigationBehavior& that) = default;
   NavigationBehavior(NavigationBehavior&& temp) = default;
-  virtual ~NavigationBehavior() = default;
+  ~NavigationBehavior() override = default;
   NavigationBehavior& operator=(const NavigationBehavior& that) = default;
   NavigationBehavior& operator=(NavigationBehavior&& temp) = default;
 
diff --git a/demos/viewer/src/viewer_system.hpp b/demos/viewer/src/viewer_system.hpp
index 82dc5c9536685b356d43e3442c08b7aaff71e4dd..dcb4d7168a8d7c85fa9139653846d83a9ef33ab4 100644
--- a/demos/viewer/src/viewer_system.hpp
+++ b/demos/viewer/src/viewer_system.hpp
@@ -31,14 +31,12 @@
 #include "phx/core/frame_timer.hpp"
 #include "phx/core/system.hpp"
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class ViewerSystem : public phx::System {
  public:
   ViewerSystem() = delete;
   ViewerSystem(const ViewerSystem&) = delete;
   ViewerSystem(ViewerSystem&&) = default;
-  ~ViewerSystem() = default;
+  ~ViewerSystem() override = default;
 
   bool GetShowFramerate() const;
   void SetShowFramerate(bool show_framerate);
@@ -58,6 +56,4 @@ class ViewerSystem : public phx::System {
   explicit ViewerSystem(phx::Engine* engine);
 };
 
-SUPPRESS_WARNINGS_END
-
 #endif  // DEMOS_VIEWER_SRC_VIEWER_SYSTEM_HPP_
diff --git a/library/phx/core/engine.hpp b/library/phx/core/engine.hpp
index 8f2f9f38ce3c43499539959cf0065bc0f5cf5e5c..fabc9c0bd93fe3fa98a91c9c1dd28950dc96b83c 100644
--- a/library/phx/core/engine.hpp
+++ b/library/phx/core/engine.hpp
@@ -43,21 +43,19 @@ SUPPRESS_WARNINGS_END
 #include "phx/core/frame_timer.hpp"
 #include "phx/core/scene.hpp"
 #include "phx/core/system.hpp"
+#include "phx/export.hpp"
 #include "phx/scripting/behavior.hpp"
 #include "phx/utility/aspects/loggable.hpp"
 #include "phx/utility/orderable_list.hpp"
-#include "phx/export.hpp"
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class PHOENIX_EXPORT Engine final : public Loggable {
  public:
   Engine();
   Engine(const Engine&) = delete;
   Engine(Engine&&) = default;
-  ~Engine();
+  ~Engine() override;
 
   Engine& operator=(const Engine&) = delete;
   Engine& operator=(Engine&&) = default;
@@ -165,8 +163,6 @@ std::vector<std::tuple<Components*...>> Engine::GetFirstComponentsMany() const {
   return scene_->GetFirstComponentsMany<Components...>();
 }
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace phx
 
 #endif  // LIBRARY_PHX_CORE_ENGINE_HPP_
diff --git a/library/phx/core/entity.hpp b/library/phx/core/entity.hpp
index 51bffc058a592a266ab21e9ba1740688ce54cf53..993438548637bb1baa3fb112dad705b52456e217 100644
--- a/library/phx/core/entity.hpp
+++ b/library/phx/core/entity.hpp
@@ -47,7 +47,7 @@ class PHOENIX_EXPORT Entity : public Nameable, public Loggable {
   explicit Entity(const std::string& name) : Nameable(name) {}
   Entity(const Entity&) = delete;
   Entity(Entity&&) = default;
-  virtual ~Entity() = default;
+  ~Entity() override = default;
 
   Entity& operator=(const Entity&) = delete;
   Entity& operator=(Entity&&) = default;
diff --git a/library/phx/core/scene.hpp b/library/phx/core/scene.hpp
index 6d4ba7d6b353587bbbc4f963ec86c058b66388e9..b4eb2d82437ab78d620b7d74c231bd2b85e4f74e 100644
--- a/library/phx/core/scene.hpp
+++ b/library/phx/core/scene.hpp
@@ -49,7 +49,7 @@ class PHOENIX_EXPORT Scene : public Nameable, public Loggable {
   Scene();
   Scene(const Scene&) = delete;
   Scene(Scene&&) = default;
-  ~Scene() = default;
+  ~Scene() override = default;
 
   Scene& operator=(const Scene&) = delete;
   Scene& operator=(Scene&&) = default;
diff --git a/library/phx/display/display_system.hpp b/library/phx/display/display_system.hpp
index fd06a71bcaa5b4dc3f3f3298da08113f5ce1105c..96d78f7f662980cff91fb7294972ba6cad778344 100644
--- a/library/phx/display/display_system.hpp
+++ b/library/phx/display/display_system.hpp
@@ -37,7 +37,7 @@ class PHOENIX_EXPORT DisplaySystem : public System {
  public:
   DisplaySystem(const DisplaySystem&) = delete;
   DisplaySystem(DisplaySystem&&) = default;
-  ~DisplaySystem();
+  ~DisplaySystem() override;
 
   DisplaySystem& operator=(const DisplaySystem&) = delete;
   DisplaySystem& operator=(DisplaySystem&&) = default;
diff --git a/library/phx/display/display_system_openvr.hpp b/library/phx/display/display_system_openvr.hpp
index 0fcdec3ddac0296a707c9e39afb980c87babd653..eb1c50dace48a0a776c12e78e6e823f779393237 100644
--- a/library/phx/display/display_system_openvr.hpp
+++ b/library/phx/display/display_system_openvr.hpp
@@ -40,7 +40,7 @@ class PHOENIX_EXPORT DisplaySystemOpenVR : public DisplaySystem {
   explicit DisplaySystemOpenVR(Engine* engine);
   DisplaySystemOpenVR(const DisplaySystemOpenVR&) = delete;
   DisplaySystemOpenVR(DisplaySystemOpenVR&&) = default;
-  ~DisplaySystemOpenVR();
+  ~DisplaySystemOpenVR() override;
 
   DisplaySystemOpenVR& operator=(const DisplaySystemOpenVR&) = delete;
   DisplaySystemOpenVR& operator=(DisplaySystemOpenVR&&) = default;
diff --git a/library/phx/display/display_system_window.hpp b/library/phx/display/display_system_window.hpp
index 1b41d76bb2835b793bed04e3dc284ed03013a6c9..cf8a3b559bbcc58796be3b1e4b34b76d01c36392 100644
--- a/library/phx/display/display_system_window.hpp
+++ b/library/phx/display/display_system_window.hpp
@@ -41,7 +41,7 @@ class PHOENIX_EXPORT DisplaySystemWindow : public DisplaySystem {
   explicit DisplaySystemWindow(Engine* engine);
   DisplaySystemWindow(const DisplaySystemWindow&) = delete;
   DisplaySystemWindow(DisplaySystemWindow&&) = default;
-  ~DisplaySystemWindow();
+  ~DisplaySystemWindow() override;
 
   DisplaySystemWindow& operator=(const DisplaySystemWindow&) = delete;
   DisplaySystemWindow& operator=(DisplaySystemWindow&&) = default;
diff --git a/library/phx/display/hmd.cpp b/library/phx/display/hmd.cpp
index c43329e2076bf3ad6dca6f6bb04affa19112f743..9436e224c5a3224bb1be8c0aab26be2bcb3fe483 100644
--- a/library/phx/display/hmd.cpp
+++ b/library/phx/display/hmd.cpp
@@ -106,7 +106,7 @@ const glm::mat4& HMD::GetEyeToHeadMatrix(Side side) const {
 
 void HMD::UpdateTrackedDevices() {
   vr::VRCompositor()->WaitGetPoses(tracked_device_poses_,
-                                   vr::k_unMaxTrackedDeviceCount, NULL, 0);
+                                   vr::k_unMaxTrackedDeviceCount, nullptr, 0);
 }
 
 glm::mat4 HMD::GetHeadTransformation() {
@@ -235,9 +235,11 @@ std::unique_ptr<Image> HMD::GetControllerTexture(int id) {
             texture_map->rubTextureMapData + image_data.size(),
             image_data.begin());
   auto image = std::make_unique<phx::Image>(
-      &image_data[0], std::array<std::size_t, 2>{
-                      {static_cast<std::size_t>(texture_map->unWidth),
-                       static_cast<std::size_t>(texture_map->unHeight)}}, 32);
+      &image_data[0],
+      std::array<std::size_t, 2>{
+          {static_cast<std::size_t>(texture_map->unWidth),
+           static_cast<std::size_t>(texture_map->unHeight)}},
+      32);
 
   return image;
 }
diff --git a/library/phx/input/input_system.hpp b/library/phx/input/input_system.hpp
index bd9d6076aa905c46fec92866711bdd4321cc7490..9862ea78119438869c1e37162909df8c9faba169 100644
--- a/library/phx/input/input_system.hpp
+++ b/library/phx/input/input_system.hpp
@@ -45,7 +45,7 @@ class PHOENIX_EXPORT InputSystem : public System {
   InputSystem() = delete;
   InputSystem(const InputSystem&) = delete;
   InputSystem(InputSystem&&) = default;
-  virtual ~InputSystem();
+  ~InputSystem() override;
 
   void Update(const FrameTimer::TimeInfo& time_info) override;
 
@@ -73,20 +73,12 @@ class PHOENIX_EXPORT InputSystem : public System {
 
   void UpdateSDLEvents();
 
-  // TODO(@tvierjahn) check if Wpadded is here only emitted by some clang
-  // versions.
-  // There will be only one input system.Padding will not waste
-  // significant memory
-  SUPPRESS_WARNINGS_BEGIN_PADDED
-
   boost::signals2::signal<void()> quit_signal_;
   boost::signals2::signal<void(char)> key_press_signal_;
   boost::signals2::signal<void(char)> key_release_signal_;
   boost::signals2::signal<void(int, int)> mouse_move_signal_;
   boost::signals2::signal<void(unsigned int)> mouse_press_signal_;
   boost::signals2::signal<void(unsigned int)> mouse_release_signal_;
-
-  SUPPRESS_WARNINGS_END
 };
 
 }  // namespace phx
diff --git a/library/phx/input/openvr_controller_behavior.hpp b/library/phx/input/openvr_controller_behavior.hpp
index c31643b67d511b4a813eb82e0d75db5f0039648d..99483e41811c55be517c7eb80fde13b3d20d5153 100644
--- a/library/phx/input/openvr_controller_behavior.hpp
+++ b/library/phx/input/openvr_controller_behavior.hpp
@@ -25,11 +25,10 @@
 
 #include "phx/suppress_warnings.hpp"
 
-#include "phx/scripting/behavior.hpp"
 #include "phx/export.hpp"
+#include "phx/scripting/behavior.hpp"
 
 namespace phx {
-SUPPRESS_WARNINGS_BEGIN_PADDED
 class PHOENIX_EXPORT OpenVRControllerBehavior : public Behavior {
  public:
   enum Side { LEFT, RIGHT };
@@ -42,7 +41,6 @@ class PHOENIX_EXPORT OpenVRControllerBehavior : public Behavior {
  private:
   Side side_ = Side::LEFT;
 };
-SUPPRESS_WARNINGS_END
 }  // namespace phx
 
 #endif  // LIBRARY_PHX_INPUT_OPENVR_CONTROLLER_BEHAVIOR_HPP_
diff --git a/library/phx/input/openvr_controller_system.hpp b/library/phx/input/openvr_controller_system.hpp
index c382d2585a76e56a4c2cdcaa7215bb7c9fa09011..607f72a46f02a0db1a33f1457ada5583f27f3e97 100644
--- a/library/phx/input/openvr_controller_system.hpp
+++ b/library/phx/input/openvr_controller_system.hpp
@@ -45,7 +45,7 @@ class PHOENIX_EXPORT OpenVRControllerSystem : public System {
   OpenVRControllerSystem() = delete;
   OpenVRControllerSystem(const OpenVRControllerSystem&) = delete;
   OpenVRControllerSystem(OpenVRControllerSystem&&) = default;
-  virtual ~OpenVRControllerSystem() = default;
+  ~OpenVRControllerSystem() override = default;
 
   OpenVRControllerSystem& operator=(const OpenVRControllerSystem&) = delete;
   OpenVRControllerSystem& operator=(OpenVRControllerSystem&&) = default;
diff --git a/library/phx/rendering/auxiliary/splash_screen.hpp b/library/phx/rendering/auxiliary/splash_screen.hpp
index 2a9007e7b2a870d788a5492fef07de605364332a..56faa94f741e3296f50dc891a5fe0f7d92428bbd 100644
--- a/library/phx/rendering/auxiliary/splash_screen.hpp
+++ b/library/phx/rendering/auxiliary/splash_screen.hpp
@@ -38,7 +38,6 @@
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
 class PHOENIX_EXPORT SplashScreen : public System {
  public:
   SplashScreen() = delete;
@@ -65,7 +64,6 @@ class PHOENIX_EXPORT SplashScreen : public System {
   std::mutex load_progress_mutex_;
   float load_progress_ = 0.f;
 };
-SUPPRESS_WARNINGS_END
 
 }  // namespace phx
 
diff --git a/library/phx/rendering/backend/render_target.hpp b/library/phx/rendering/backend/render_target.hpp
index be07213d041ca9e41aec02c17b72d5e00f56090f..bed8eda040f06f9c5916be24de53b12962be7908 100644
--- a/library/phx/rendering/backend/render_target.hpp
+++ b/library/phx/rendering/backend/render_target.hpp
@@ -43,7 +43,6 @@ SUPPRESS_WARNINGS_END
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
 class PHOENIX_EXPORT RenderTarget : public Component, public gl::framebuffer {
  public:
   RenderTarget() = delete;
@@ -69,7 +68,6 @@ class PHOENIX_EXPORT RenderTarget : public Component, public gl::framebuffer {
 
   glm::uvec2 dimensions_;
 };
-SUPPRESS_WARNINGS_END
 
 }  // namespace phx
 
diff --git a/library/phx/rendering/backend/shader_program.hpp b/library/phx/rendering/backend/shader_program.hpp
index 93c6d7a56319bc436740a4e938fba132490a00ec..679130847e0cc4b611c486eb881fff57b752d819 100644
--- a/library/phx/rendering/backend/shader_program.hpp
+++ b/library/phx/rendering/backend/shader_program.hpp
@@ -37,19 +37,15 @@ SUPPRESS_WARNINGS_END
 #include "gl/program.hpp"
 #include "gl/shader.hpp"
 
+#include "phx/export.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "phx/rendering/render_passes/render_pass.hpp"
+#include "phx/resources/resource_pointer.hpp"
 #include "phx/resources/types/mesh.hpp"
 #include "phx/resources/types/shader_source.hpp"
-#include "phx/resources/resource_pointer.hpp"
-#include "phx/export.hpp"
 
 namespace phx {
 
-// TODO(@all) Will padding waste too much memory? How many shaders will we
-// have?
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class PHOENIX_EXPORT ShaderProgram : public gl::program {
  public:
   enum ShaderChannel {
@@ -71,7 +67,7 @@ class PHOENIX_EXPORT ShaderProgram : public gl::program {
   ShaderProgram& operator=(ShaderProgram&&) = default;
 
   bool SetShader(ShaderChannel channel,
-                      ResourcePointer<ShaderSource> shader_source);
+                 ResourcePointer<ShaderSource> shader_source);
 
   template <typename T>
   void SetUniform(const std::string& name, T value) {
@@ -91,8 +87,6 @@ class PHOENIX_EXPORT ShaderProgram : public gl::program {
   std::array<ShaderHandle, MAX_SHADER_CHANNEL> shaders_;
 };
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace phx
 
 #endif  // LIBRARY_PHX_RENDERING_BACKEND_SHADER_PROGRAM_HPP_
diff --git a/library/phx/rendering/components/light.hpp b/library/phx/rendering/components/light.hpp
index e8abc925810b1d63db905fad6a885e2843d2cb90..9c0403289ad1584c5ad8463b233cb6a001917679 100644
--- a/library/phx/rendering/components/light.hpp
+++ b/library/phx/rendering/components/light.hpp
@@ -36,8 +36,6 @@ SUPPRESS_WARNINGS_END
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class PHOENIX_EXPORT Light final : public Component {
  public:
   enum class Type {
@@ -80,8 +78,6 @@ class PHOENIX_EXPORT Light final : public Component {
   float spot_angle_ = 45.0f;  // Only for spot lights.
 };
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace phx
 
 #endif  // LIBRARY_PHX_RENDERING_COMPONENTS_LIGHT_HPP_
diff --git a/library/phx/rendering/components/mesh_handle.hpp b/library/phx/rendering/components/mesh_handle.hpp
index 5bbf59c677ff2ea2d6d9fa9160b361d38e603e7d..52ba4594f6f92424ede2e80fc7881757ed1c5b42 100644
--- a/library/phx/rendering/components/mesh_handle.hpp
+++ b/library/phx/rendering/components/mesh_handle.hpp
@@ -36,7 +36,7 @@ namespace phx {
  */
 class PHOENIX_EXPORT MeshHandle final : public Component, public Nameable {
  public:
-  virtual ~MeshHandle() = default;
+  ~MeshHandle() override = default;
 
   void SetMesh(ResourcePointer<Mesh> mesh);
   ResourcePointer<Mesh> GetMesh() const;
diff --git a/library/phx/rendering/components/transform.hpp b/library/phx/rendering/components/transform.hpp
index b67c14855ba21e89aeb98eb9f80fda9f625a0fc9..c9e4f0c30f96753ad51946118f3e3d0628d0407f 100644
--- a/library/phx/rendering/components/transform.hpp
+++ b/library/phx/rendering/components/transform.hpp
@@ -44,7 +44,7 @@ namespace phx {
 class PHOENIX_EXPORT Transform : public Component,
                                  public Hierarchical<Transform> {
  public:
-  virtual ~Transform() = default;
+  ~Transform() override = default;
 
   // Getting/Setting Local transform
   const glm::vec3& GetLocalTranslation() const;
diff --git a/library/phx/rendering/render_passes/geometry_pass.hpp b/library/phx/rendering/render_passes/geometry_pass.hpp
index bd2edb0c40e650bf294feac2a7834babe3c53570..0b2104f103ee0ffa9a0ce2afd147d89630c36862 100644
--- a/library/phx/rendering/render_passes/geometry_pass.hpp
+++ b/library/phx/rendering/render_passes/geometry_pass.hpp
@@ -36,6 +36,7 @@ SUPPRESS_WARNINGS_BEGIN
 #include "gl/vertex_array.hpp"
 SUPPRESS_WARNINGS_END
 
+#include "phx/export.hpp"
 #include "phx/rendering/backend/render_target.hpp"
 #include "phx/rendering/backend/shader_program.hpp"
 #include "phx/rendering/components/light.hpp"
@@ -43,14 +44,11 @@ SUPPRESS_WARNINGS_END
 #include "phx/rendering/components/projection.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "phx/rendering/render_passes/render_pass.hpp"
-#include "phx/resources/types/mesh.hpp"
 #include "phx/resources/resource_manager.hpp"
-#include "phx/export.hpp"
+#include "phx/resources/types/mesh.hpp"
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class PHOENIX_EXPORT GeometryPass : public RenderPass {
  public:
   explicit GeometryPass(RenderTarget* render_target);
@@ -87,8 +85,6 @@ class PHOENIX_EXPORT GeometryPass : public RenderPass {
   bool IsValid() const;
 
  private:
-  // TODO(@all) Will padding waste too much memory?
-  SUPPRESS_WARNINGS_BEGIN_PADDED
   struct RenderingResource {
     RenderingResource() = default;
     RenderingResource(const RenderingResource&) = delete;
@@ -107,7 +103,6 @@ class PHOENIX_EXPORT GeometryPass : public RenderPass {
     unsigned int vertex_buffer_size;
     unsigned int index_buffer_size;
   };
-  SUPPRESS_WARNINGS_END
 
   void SetUpShaders();
   void CreateRenderingResource();
@@ -136,8 +131,6 @@ class PHOENIX_EXPORT GeometryPass : public RenderPass {
   RenderTarget* render_target_;
 };
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace phx
 
 #endif  // LIBRARY_PHX_RENDERING_RENDER_PASSES_GEOMETRY_PASS_HPP_
diff --git a/library/phx/rendering/rendering_system.hpp b/library/phx/rendering/rendering_system.hpp
index 6d56ee71d065e304d9482dc023b099d30a87a77a..e33def770c5e7d7c64b7c6bb0ae97e7f1460fe3f 100644
--- a/library/phx/rendering/rendering_system.hpp
+++ b/library/phx/rendering/rendering_system.hpp
@@ -44,7 +44,7 @@ class PHOENIX_EXPORT RenderingSystem : public System {
   RenderingSystem() = delete;
   RenderingSystem(const RenderingSystem&) = delete;
   RenderingSystem(RenderingSystem&&) = default;
-  virtual ~RenderingSystem() = default;
+  ~RenderingSystem() override = default;
 
   void Update(const FrameTimer::TimeInfo& time_info) override;
 
diff --git a/library/phx/resources/loaders/assimp_model_loader.hpp b/library/phx/resources/loaders/assimp_model_loader.hpp
index 9f5abd2073008c220b8b1aea02d50a0cc2b3b5b6..5b7777567c1c0a907194c4866ae77979b001134f 100644
--- a/library/phx/resources/loaders/assimp_model_loader.hpp
+++ b/library/phx/resources/loaders/assimp_model_loader.hpp
@@ -39,16 +39,15 @@ SUPPRESS_WARNINGS_BEGIN
 SUPPRESS_WARNINGS_END
 
 #include "phx/export.hpp"
-#include "phx/resources/types/material.hpp"
-#include "phx/resources/types/mesh.hpp"
-#include "phx/resources/types/model.hpp"
 #include "phx/resources/resource_declaration.hpp"
 #include "phx/resources/resource_load_strategy.hpp"
 #include "phx/resources/resource_pointer.hpp"
+#include "phx/resources/types/material.hpp"
+#include "phx/resources/types/mesh.hpp"
+#include "phx/resources/types/model.hpp"
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
 class PHOENIX_EXPORT AssimpModelLoader final : public ResourceLoadStrategy {
  public:
   AssimpModelLoader();
@@ -114,7 +113,6 @@ class PHOENIX_EXPORT AssimpModelLoader final : public ResourceLoadStrategy {
   int last_material_index_ = kInvalidMaterialIndex;
   std::function<void(float)> on_progress_update_callback_;
 };
-SUPPRESS_WARNINGS_END
 
 template <typename FileSourceType>
 std::vector<glm::vec3> phx::AssimpModelLoader::LoadVectorData(
diff --git a/library/phx/resources/loaders/image_loader.hpp b/library/phx/resources/loaders/image_loader.hpp
index aaebda26146ff3e81c26ee33369a6dfe93e99961..9e0e61fb4f42d357e1689460a12100069acf2a4b 100644
--- a/library/phx/resources/loaders/image_loader.hpp
+++ b/library/phx/resources/loaders/image_loader.hpp
@@ -35,7 +35,7 @@ class ImageLoader final : public ResourceLoadStrategy {
   ImageLoader() = default;
   ImageLoader(const ImageLoader &) = delete;
   ImageLoader(ImageLoader &&) = delete;
-  ~ImageLoader() = default;
+  ~ImageLoader() override = default;
 
   ImageLoader &operator=(const ImageLoader &) = delete;
   ImageLoader &operator=(ImageLoader &&) = delete;
diff --git a/library/phx/resources/loaders/shader_loader.hpp b/library/phx/resources/loaders/shader_loader.hpp
index a23444fa3d7df4e823a3a31cd8fe9341c8ef8c96..3f2a816001083ab8ddd73849bd48183641fc608c 100644
--- a/library/phx/resources/loaders/shader_loader.hpp
+++ b/library/phx/resources/loaders/shader_loader.hpp
@@ -35,7 +35,7 @@ class ShaderLoader final : public ResourceLoadStrategy {
   ShaderLoader() = default;
   ShaderLoader(const ShaderLoader&) = delete;
   ShaderLoader(ShaderLoader&&) = delete;
-  ~ShaderLoader() = default;
+  ~ShaderLoader() override = default;
 
   ShaderLoader& operator=(const ShaderLoader&) = delete;
   ShaderLoader& operator=(ShaderLoader&&) = delete;
diff --git a/library/phx/resources/types/image.hpp b/library/phx/resources/types/image.hpp
index a5497948d3270f868eee852939ae1a27acdfe367..8638e7bb8f9522751fa44555848248fd05ce3cbd 100644
--- a/library/phx/resources/types/image.hpp
+++ b/library/phx/resources/types/image.hpp
@@ -81,7 +81,7 @@ class PHOENIX_EXPORT Image : public Resource, public Loggable {
                  const std::int32_t native_flags = 0);
   Image(const Image& that);
   Image(Image&& temp) noexcept;
-  virtual ~Image();
+  ~Image() override;
   Image& operator=(const Image& that);
   Image& operator=(Image&& temp) noexcept;
 
diff --git a/library/phx/scripting/behavior_system.hpp b/library/phx/scripting/behavior_system.hpp
index 5513e828fc5cf1e59db20b0beabc5d914b4a4fc3..e723ab04016c3b1aa9369dd78fb0c9079a050a15 100644
--- a/library/phx/scripting/behavior_system.hpp
+++ b/library/phx/scripting/behavior_system.hpp
@@ -31,14 +31,12 @@
 
 namespace phx {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class PHOENIX_EXPORT BehaviorSystem : public System {
  public:
   BehaviorSystem() = delete;
   BehaviorSystem(const BehaviorSystem&) = delete;
   BehaviorSystem(BehaviorSystem&&) = default;
-  ~BehaviorSystem() = default;
+  ~BehaviorSystem() override = default;
 
   void Update(const FrameTimer::TimeInfo& time_info) override;
 
@@ -50,8 +48,6 @@ class PHOENIX_EXPORT BehaviorSystem : public System {
   explicit BehaviorSystem(Engine* engine);
 };
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace phx
 
 #endif  // LIBRARY_PHX_SCRIPTING_BEHAVIOR_SYSTEM_HPP_
diff --git a/library/phx/scripting/generic_behavior.cpp b/library/phx/scripting/generic_behavior.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ac991bfecc58048c6c4ea80e05e202cdba7264a
--- /dev/null
+++ b/library/phx/scripting/generic_behavior.cpp
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------
+// Project Phoenix
+//
+// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
+// Virtual Reality & Immersive Visualization Group.
+//------------------------------------------------------------------------------
+//                                 License
+//
+// Licensed under the 3-Clause BSD License (the "License");
+// you may not use this file except in compliance with the License.
+// See the file LICENSE for the full text.
+// You may obtain a copy of the License at
+//
+//     https://opensource.org/licenses/BSD-3-Clause
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//------------------------------------------------------------------------------
+
+#include "generic_behavior.hpp"
+
+#include <string>
+
+namespace phx {
+
+GenericBehavior::GenericBehavior(
+    const std::function<void(Entity*)>& on_construction,
+    const std::function<void(const FrameTimer::TimeInfo* time_info, Entity*)>&
+        on_update,
+    const std::string& name /*= "unnamed"*/)
+    : on_update_(on_update), name_(name) {
+  on_construction(GetEntity());
+}
+
+void GenericBehavior::OnUpdate() { on_update_(time_info_, GetEntity()); }
+
+std::string GenericBehavior::ToString() const {
+  return "GenericBehavior: " + name_;
+}
+
+}  // namespace phx
diff --git a/library/phx/scripting/generic_behavior.hpp b/library/phx/scripting/generic_behavior.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..cc86fb25b0499a453395c8a3bc0ca220655a9ac8
--- /dev/null
+++ b/library/phx/scripting/generic_behavior.hpp
@@ -0,0 +1,60 @@
+//------------------------------------------------------------------------------
+// Project Phoenix
+//
+// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
+// Virtual Reality & Immersive Visualization Group.
+//------------------------------------------------------------------------------
+//                                 License
+//
+// Licensed under the 3-Clause BSD License (the "License");
+// you may not use this file except in compliance with the License.
+// See the file LICENSE for the full text.
+// You may obtain a copy of the License at
+//
+//     https://opensource.org/licenses/BSD-3-Clause
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//------------------------------------------------------------------------------
+
+#ifndef LIBRARY_PHX_SCRIPTING_GENERIC_BEHAVIOR_HPP_
+#define LIBRARY_PHX_SCRIPTING_GENERIC_BEHAVIOR_HPP_
+
+#include <functional>
+#include <string>
+
+#include "phx/scripting/behavior.hpp"
+
+namespace phx {
+
+class PHOENIX_EXPORT GenericBehavior : public Behavior {
+ public:
+  GenericBehavior(
+      const std::function<void(Entity*)>& on_construction,
+      const std::function<void(const FrameTimer::TimeInfo* time_info, Entity*)>&
+          on_update,
+      const std::string& name = "unnamed");
+  GenericBehavior(const GenericBehavior&) = default;
+  GenericBehavior(GenericBehavior&&) = default;
+
+  GenericBehavior& operator=(const GenericBehavior&) = default;
+  GenericBehavior& operator=(GenericBehavior&&) = default;
+
+  ~GenericBehavior() = default;
+
+  void OnUpdate() override;
+  std::string ToString() const override;
+
+ protected:
+  std::function<void(Entity*)> on_construction_;
+  std::function<void(const FrameTimer::TimeInfo* time_info, Entity*)>
+      on_update_;
+  std::string name_;
+};
+
+}  // namespace phx
+
+#endif  // LIBRARY_PHX_SCRIPTING_GENERIC_BEHAVIOR_HPP_
diff --git a/library/phx/tracking/tracking_system_openvr.hpp b/library/phx/tracking/tracking_system_openvr.hpp
index ad35174c67e3bc5199e575e4dcff6ba65c9be1fb..d2cd2172a18097ebe5c7d6d48c7720993663a9b1 100644
--- a/library/phx/tracking/tracking_system_openvr.hpp
+++ b/library/phx/tracking/tracking_system_openvr.hpp
@@ -45,7 +45,7 @@ class PHOENIX_EXPORT TrackingSystemOpenVR : public System {
   TrackingSystemOpenVR() = delete;
   TrackingSystemOpenVR(const TrackingSystemOpenVR&) = delete;
   TrackingSystemOpenVR(TrackingSystemOpenVR&&) = default;
-  ~TrackingSystemOpenVR();
+  ~TrackingSystemOpenVR() override;
 
   TrackingSystemOpenVR& operator=(const TrackingSystemOpenVR&) = delete;
   TrackingSystemOpenVR& operator=(TrackingSystemOpenVR&&) = default;
diff --git a/library/phx/utility/aspects/hierarchical.hpp b/library/phx/utility/aspects/hierarchical.hpp
index 45dd77d166b3908678d4e8e22ceb3ba00050bcb0..a977bb77bb87011ab9926a78c7a521a038e6b7bf 100644
--- a/library/phx/utility/aspects/hierarchical.hpp
+++ b/library/phx/utility/aspects/hierarchical.hpp
@@ -34,15 +34,20 @@ namespace phx {
 template <typename Derived>
 class PHOENIX_EXPORT Hierarchical {
  public:
-  virtual ~Hierarchical() = default;
+  virtual ~Hierarchical() {
+    Hierarchical::SetParent(nullptr);
+    for (auto child : children_) {
+      child->SetParent(nullptr);
+    }
+  }
 
   virtual void SetParent(Derived* parent) {
-    if (parent_)
+    if (parent_) {
       parent_->children_.erase(
           std::remove(parent_->children_.begin(), parent_->children_.end(),
                       static_cast<Derived*>(this)),
           parent_->children_.end());
-
+    }
     parent_ = parent;
 
     if (parent_) parent_->children_.push_back(static_cast<Derived*>(this));
diff --git a/library/phx/utility/stream_helpers.hpp b/library/phx/utility/stream_helpers.hpp
index c464887c49b75208f9433a0181e50e5b2e4046db..89902b6cd7f208dc3f746915c003be3f36d55c51 100644
--- a/library/phx/utility/stream_helpers.hpp
+++ b/library/phx/utility/stream_helpers.hpp
@@ -41,7 +41,6 @@ SUPPRESS_WARNINGS_END
 // namespace like e.g. phx, leaving them in global namespace would not work
 namespace glm {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
 class PHOENIX_EXPORT PhxStreamSettings {
  public:
   explicit PhxStreamSettings(std::ostream& stream);
@@ -57,7 +56,6 @@ class PHOENIX_EXPORT PhxStreamSettings {
   std::streamsize stream_precision_;
   std::ios::fmtflags stream_flags_;
 };
-SUPPRESS_WARNINGS_END
 
 PHOENIX_EXPORT std::ostream& operator<<(std::ostream& out,
                                         const glm::vec2& vec);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7a9d51630e5abc3d55fc600d163802bf5d3266ed..80e2e28e909780bb57a346f666933cc73d6005cb 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -22,86 +22,43 @@
 
 #see at the bottom how to add mocked tests
 
-# configure reference image directory include string
-set(_REFIMAGE_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/reference_images/")
-set(SOURCE_REFIMAGE_INCLUDE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/test_utilities/reference_image_path.hpp.template")
-set(TARGET_REFIMAGE_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_utilities/reference_image_path.hpp")
-configure_file(${SOURCE_REFIMAGE_INCLUDE_FILE} ${TARGET_REFIMAGE_INCLUDE_FILE} @ONLY)
-
 file(GLOB PHOENIX_TEST_SOURCES src/*.cpp)
 file(GLOB PHOENIX_TEST_HEADERS src/*.hpp)
 file(GLOB PHOENIX_TEST_UTILITIES_TEST_SOURCES test_utilities/tests/src/*.cpp)
 file(GLOB PHOENIX_TEST_UTILITIES_HEADERS test_utilities/*.hpp)
 file(GLOB PHOENIX_TEST_UTILITIES_SOURCES test_utilities/*.cpp)
+file(GLOB TEST_MAIN_SOURCES src/tests.cpp)
+file(GLOB MOCK_MAIN_SOURCES src/mocks/mocks.cpp)
 
-#get the include directories
-get_target_property(glew_include_directories
-  ${CONAN_OR_CMAKE_glew} INTERFACE_INCLUDE_DIRECTORIES)
-get_target_property(phoenix_include_directories 
-  phoenix INCLUDE_DIRECTORIES)
-get_target_property(sdl2_include_directories
-  ${CONAN_OR_CMAKE_sdl2} INTERFACE_INCLUDE_DIRECTORIES)
-get_target_property(openvr_include_directories
-  ${CONAN_OR_CMAKE_openvr} INTERFACE_INCLUDE_DIRECTORIES)
-get_target_property(gl_include_directories
-  ${CONAN_OR_CMAKE_gl} INTERFACE_INCLUDE_DIRECTORIES)
-
-
-macro(add_mock_lib mock_name mock_src_path)
-  add_library(${mock_name} SHARED
-    ${mock_src_path}/${mock_name}.cpp
-    ${mock_src_path}/${mock_name}.hpp
+
+create_test_main(
+  SOURCES ${TEST_MAIN_SOURCES}
+  LIBRARIES ${CONAN_OR_CMAKE_catch}
   )
-  target_link_libraries(${mock_name}
-    ${CONAN_OR_CMAKE_trompeloeil})
-  #phx include dirs needed for suppress_warnings.hpp
-  target_include_directories(${mock_name}
-    PRIVATE ${phoenix_include_directories})
-  set_property(TARGET ${mock_name} PROPERTY FOLDER "Tests")
-  set_warning_levels_rwth(${mock_name})
-endmacro()
+list(REMOVE_ITEM PHOENIX_TEST_SOURCES ${TEST_MAIN_SOURCES})
 
-# generate opengl_mock
-set( OPENGL_MOCK_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/mocks)
-set( OPENGL_MOCK_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/generation/Create_openGL_mock.py)
-if( NOT EXISTS ${OPENGL_MOCK_SOURCE}/opengl_mock.cpp OR 
-    ${OPENGL_MOCK_GENERATOR} IS_NEWER_THAN 
-    ${OPENGL_MOCK_SOURCE}/opengl_mock.cpp)
-  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocks")
-  EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} 
-    "${OPENGL_MOCK_GENERATOR}" 
-    -g "${glew_include_directories}" 
-    -m "${OPENGL_MOCK_SOURCE}/" 
-    -t "${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/generation/")
-endif()
+create_mock_main(
+  SOURCES ${MOCK_MAIN_SOURCES}
+  LIBRARIES ${CONAN_OR_CMAKE_catch} ${CONAN_OR_CMAKE_trompeloeil}
+  )
+list(REMOVE_ITEM PHOENIX_TEST_SOURCES ${MOCK_MAIN_SOURCES})
+
+
+# configure reference image directory include string
+set(_REFIMAGE_ROOT_PATH
+  "${CMAKE_CURRENT_SOURCE_DIR}/reference_images/"
+  )
+set(SOURCE_REFIMAGE_INCLUDE_FILE
+  "${CMAKE_CURRENT_SOURCE_DIR}/test_utilities/reference_image_path.hpp.template"
+  )
+set(TARGET_REFIMAGE_INCLUDE_FILE
+  "${CMAKE_CURRENT_BINARY_DIR}/test_utilities/reference_image_path.hpp"
+  )
+configure_file(${SOURCE_REFIMAGE_INCLUDE_FILE}
+  ${TARGET_REFIMAGE_INCLUDE_FILE}
+  @ONLY
+  )
 
-add_mock_lib(opengl_mock ${OPENGL_MOCK_SOURCE})
-target_include_directories(opengl_mock
-  PUBLIC ${OPENGL_MOCK_SOURCE}
-  PUBLIC ${glew_include_directories})
-target_compile_definitions(opengl_mock
-  PRIVATE OPENGL_MOCK_BUILD)
-generate_export_header(opengl_mock
-  EXPORT_FILE_NAME ${OPENGL_MOCK_SOURCE}/opengl_mock_export.hpp
-)
-
-# generate openvr_mock
-add_mock_lib(openvr_mock ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks)
-target_include_directories(openvr_mock
-  PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src
-  PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/mocks
-  PUBLIC ${openvr_include_directories})
-target_compile_definitions(openvr_mock
-  PRIVATE OPENVR_MOCK_BUILD)
-generate_export_header(openvr_mock
-  EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/mocks/openvr_mock_export.hpp
-)
-
-#the opengl mock gets quite large due to the trompleoeil templates
-if(MSVC)
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
-	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
-endif(MSVC)
 
 # generate test_utilities
 add_library(test_utilities STATIC
@@ -120,82 +77,78 @@ target_link_libraries(test_utilities
 set_warning_levels_rwth(test_utilities)
 
 
+# generate opengl_mock
+get_target_property(glew_include_directories
+  ${CONAN_OR_CMAKE_glew} INTERFACE_INCLUDE_DIRECTORIES)
+set( OPENGL_MOCK_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/mocks)
+set( OPENGL_MOCK_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/generation/Create_openGL_mock.py)
+if( NOT EXISTS ${OPENGL_MOCK_SOURCE}/opengl_mock.cpp OR 
+    ${OPENGL_MOCK_GENERATOR} IS_NEWER_THAN 
+    ${OPENGL_MOCK_SOURCE}/opengl_mock.cpp)
+  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocks")
+  EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} 
+    "${OPENGL_MOCK_GENERATOR}" 
+    -g "${glew_include_directories}" 
+    -m "${OPENGL_MOCK_SOURCE}/" 
+    -t "${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/generation/")
+endif()
+
 #get the gl link library
 if(TARGET CONAN_LIB::gl_gl)
-  get_target_property(gl_link_library CONAN_LIB::gl_gl LOCATION)
+  get_target_property(GL_LIBRARY CONAN_LIB::gl_gl LOCATION)
 elseif(TARGET CONAN_LIB::gl_glrelease)
-  get_target_property(gl_imported_location_rel CONAN_LIB::gl_glrelease LOCATION)
-  get_target_property(gl_imported_location_deb CONAN_LIB::gl_gldebug LOCATION)
-  set(gl_link_library "$<$<CONFIG:Release>:${gl_imported_location_rel}>$<$<CONFIG:Debug>:${gl_imported_location_deb}>")
-else()
-  message(FATAL_ERROR "You are using a conan version older than 0.29, please update e.g. by \"pip install conan --upgrade\"")
+  get_target_property(GL_LIBRARY_LOCATION_RELEASE
+    CONAN_LIB::gl_glrelease LOCATION)
+  get_target_property(GL_LIBRARY_LOCATION_DEBUG
+    CONAN_LIB::gl_gldebug LOCATION)
+  set(GL_LIBRARY
+    "$<$<CONFIG:Release>:${GL_LIBRARY_LOCATION_RELEASE}>$<$<CONFIG:Debug>:${GL_LIBRARY_LOCATION_DEBUG}>")
 endif()
+  
+add_mock(
+  NAME opengl_mock
+  SOURCES ${CMAKE_CURRENT_BINARY_DIR}/mocks/opengl_mock.cpp
+  HEADERS ${CMAKE_CURRENT_BINARY_DIR}/mocks/opengl_mock.hpp
+  INCLUDE_DIRECTORIES
+    ${CMAKE_CURRENT_BINARY_DIR}
+  INCLUDE_DIRECTORIES_OF
+    phoenix
+    ${CONAN_OR_CMAKE_gl}
+    ${CONAN_OR_CMAKE_glew}
+  COMPILE_OPTIONS $<$<CXX_COMPILER_ID:MSVC>:/bigobj>
+  REMOVES_LIBRARIES
+    ${CONAN_OR_CMAKE_gl}
+    ${CONAN_OR_CMAKE_glew}
+    ${CONAN_OR_CMAKE_sdl2}
+    ${OPENGL_LIBRARIES}
+  ADDS_LIBRARIES ${GL_LIBRARY}
+  )
 
-set(IS_BUILD_SERVER FALSE CACHE BOOL "Is this the build server? So we, e.g., simulate user input for tests requiring it.")
-
-
-macro(add_mocked_test cpp_file)
-  set(options MOCK_GLEW MOCK_SDL MOCK_OPENVR)
-  set(oneValueArgs )
-  set(multiValueArgs )
-  cmake_parse_arguments(ADD_MOCKED_TEST
-    "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
-  list(REMOVE_ITEM PHOENIX_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/${cpp_file}.cpp)
-
-  set(test_sources src/tests.cpp src/${cpp_file}.cpp)
-  add_executable(${cpp_file} ${test_sources})
-
-  add_dependencies(${cpp_file} phoenix test_utilities)
-
-  ADD_TEST_CATCH_INTERNAL_(${cpp_file} ${test_sources} "")
-
-  # make shure linker dependency injection works
-  target_include_directories(${cpp_file}
-    PRIVATE ${phoenix_include_directories}
-    PRIVATE ${glew_include_directories}
-	PRIVATE ${gl_include_directories}
-    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
-    PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-
-  get_target_property(phoenix_link_libraries phoenix LINK_LIBRARIES)
-
-  if(${ADD_MOCKED_TEST_MOCK_GLEW})
-    list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_gl})
-    list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_glew})
-    #SDL has also to be removed since it contains OpenGL
-    list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_sdl2})
-    list(REMOVE_ITEM phoenix_link_libraries ${OPENGL_LIBRARIES})
-    list(APPEND phoenix_link_libraries opengl_mock)
-    list(APPEND phoenix_link_libraries ${gl_link_library})
-	
-  endif(${ADD_MOCKED_TEST_MOCK_GLEW})
-
-  if(${ADD_MOCKED_TEST_MOCK_SDL})
-    target_sources(${cpp_file}
-      PRIVATE src/mocks/sdl_mock.cpp
-      PRIVATE src/mocks/sdl_mock.hpp)
-    target_compile_definitions(${cpp_file} PRIVATE TESTING)
-    target_include_directories(${cpp_file}
-      PRIVATE ${sdl2_include_directories})
-    list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_sdl2})
-  endif(${ADD_MOCKED_TEST_MOCK_SDL})
-
-  if(${ADD_MOCKED_TEST_MOCK_OPENVR})
-    list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_openvr})
-    list(APPEND phoenix_link_libraries openvr_mock)
-  endif(${ADD_MOCKED_TEST_MOCK_OPENVR})
-
-  target_link_libraries(${cpp_file}
-    ${CONAN_OR_CMAKE_trompeloeil}
-    ${CONAN_OR_CMAKE_catch}
-	$<TARGET_FILE:phoenix>
-    ${phoenix_link_libraries}
-    $<TARGET_FILE:test_utilities>
+add_mock(
+  NAME openvr_mock
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/openvr_mock.cpp
+  HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/openvr_mock.hpp
+  INCLUDE_DIRECTORIES
+    ${CMAKE_CURRENT_SOURCE_DIR}/src
+    ${CMAKE_CURRENT_BINARY_DIR}
+  INCLUDE_DIRECTORIES_OF
+    phoenix
+    ${CONAN_OR_CMAKE_openvr}
+  REMOVES_LIBRARIES ${CONAN_OR_CMAKE_openvr}
   )
-endmacro()
 
+add_mock(
+  NAME sdl_mock
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/sdl_mock.cpp
+  HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/mocks/sdl_mock.hpp
+  INCLUDE_DIRECTORIES
+    ${CMAKE_CURRENT_SOURCE_DIR}/src
+    ${CMAKE_CURRENT_BINARY_DIR}
+  INCLUDE_DIRECTORIES_OF
+    phoenix
+    ${CONAN_OR_CMAKE_sdl2}
+  REMOVES_LIBRARIES ${CONAN_OR_CMAKE_sdl2}
+  )
 
 
 # these have to go before the mocked tests.
@@ -214,37 +167,74 @@ add_test_cpplint(NAME "phoenix-tests--cpplint"
   ${PHOENIX_TEST_UTILITIES_SOURCES}
 )
 
-#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------
 
 # Only tests that require mocking need to be specified separately here.
-# By doing so they are removed from ${PHOENIX_TEST_SOURCES} automatically.
-add_mocked_test(test_clear_pass MOCK_GLEW)
-add_mocked_test(test_input_system MOCK_SDL MOCK_OPENVR)
-add_mocked_test(test_geometry_pass MOCK_GLEW MOCK_SDL)
-add_mocked_test(test_rendering_system MOCK_GLEW MOCK_SDL)
-add_mocked_test(test_shader MOCK_GLEW)
-add_mocked_test(test_display_system MOCK_SDL)
-add_mocked_test(test_engine MOCK_SDL MOCK_OPENVR MOCK_GLEW)
-add_mocked_test(test_tracking_system MOCK_SDL MOCK_OPENVR)
-add_mocked_test(test_openvr_controller_system MOCK_SDL MOCK_OPENVR MOCK_GLEW)
-
-add_mocked_test(integration_test_model_rendering MOCK_OPENVR)
-add_mocked_test(integration_test_opengl_buffer_data_download MOCK_OPENVR)
-add_mocked_test(integration_test_rendering MOCK_OPENVR)
-add_mocked_test(integration_test_hmd MOCK_OPENVR)
-
-#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------
-
-
-add_test_catch(NAME "phoenix-tests"
+# By doing so they are removed from the list of sources
+# specified via AUTOREMOVE_MOCKED_TEST_SOURCE_FROM
+autoremove_mocked_test_source_from(${PHOENIX_TEST_SOURCES})
+
+add_mocked_test(test_clear_pass
+  LIBRARIES phoenix
+  MOCKS opengl_mock
+)
+add_mocked_test(test_input_system
+  LIBRARIES phoenix
+  MOCKS openvr_mock sdl_mock
+)
+add_mocked_test(test_geometry_pass
+  LIBRARIES phoenix test_utilities
+  MOCKS opengl_mock sdl_mock
+)
+add_mocked_test(test_rendering_system
+  LIBRARIES phoenix
+  MOCKS opengl_mock sdl_mock
+)
+add_mocked_test(test_shader
+  LIBRARIES phoenix
+  MOCKS opengl_mock
+)
+add_mocked_test(test_display_system
+  LIBRARIES phoenix
+  MOCKS sdl_mock
+)
+add_mocked_test(test_engine
+  LIBRARIES phoenix test_utilities
+  MOCKS opengl_mock openvr_mock sdl_mock
+)
+add_mocked_test(test_tracking_system
+  LIBRARIES phoenix test_utilities
+  MOCKS openvr_mock sdl_mock
+)
+add_mocked_test(test_openvr_controller_system
+  LIBRARIES phoenix
+  MOCKS opengl_mock openvr_mock sdl_mock
+)
+
+add_mocked_test(integration_test_model_rendering
+  LIBRARIES phoenix test_utilities
+  MOCKS openvr_mock
+)
+add_mocked_test(integration_test_opengl_buffer_data_download
+  LIBRARIES phoenix test_utilities
+  MOCKS openvr_mock
+)
+add_mocked_test(integration_test_rendering
+  LIBRARIES phoenix test_utilities
+  MOCKS openvr_mock
+)
+add_mocked_test(integration_test_hmd
+  LIBRARIES phoenix test_utilities
+  MOCKS openvr_mock
+)
+
+get_unmocked_test_sources(PHOENIX_TEST_SOURCES)
+
+# This adds all cpp files in tests as single tests that were not used with
+# add_mocked_test() above
+add_tests(NAME "phoenix-tests"
   SOURCES ${PHOENIX_TEST_SOURCES} ${PHOENIX_TEST_UTILITIES_TEST_SOURCES}
   HEADERS ${PHOENIX_TEST_HEADERS}
-  CATCH_MAIN src/tests.cpp
-  INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} phoenix
-  LINK_LIBRARIES phoenix test_utilities
+  INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+  LIBRARIES phoenix test_utilities
   PATH_TO_ADD ${PROJECT_BINARY_DIR}/library
 )
-
-
diff --git a/tests/src/mocks/mocks.cpp b/tests/src/mocks/mocks.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..73334bc45712e87a4b20bbf33cee8eff29543345
--- /dev/null
+++ b/tests/src/mocks/mocks.cpp
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+// Project Phoenix
+//
+// Copyright (c) 2018 RWTH Aachen University, Germany,
+// Virtual Reality & Immersive Visualization Group.
+//------------------------------------------------------------------------------
+//                                 License
+//
+// Licensed under the 3-Clause BSD License (the "License");
+// you may not use this file except in compliance with the License.
+// See the file LICENSE for the full text.
+// You may obtain a copy of the License at
+//
+//     https://opensource.org/licenses/BSD-3-Clause
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//------------------------------------------------------------------------------
+
+#include "catch/catch.hpp"
+
+#include "trompeloeil.hpp"
+
+namespace trompeloeil {
+template <>
+void reporter<specialized>::send(severity s, const char* file,  // NOLINT
+                                 unsigned long line,            // NOLINT
+                                 const char* msg) {             // NOLINT
+  std::ostringstream os;
+  if (line) os << file << ':' << line << '\n';
+  os << msg;
+  auto failure = os.str();
+  if (s == severity::fatal) {
+    FAIL(failure);
+  } else {
+    CAPTURE(failure);
+    CHECK(failure.empty());
+  }
+}
+}  // namespace trompeloeil
diff --git a/tests/src/mocks/openvr_mock.hpp b/tests/src/mocks/openvr_mock.hpp
index 83ec13827c371fd43eb7406175ab4393cb5867bd..855e2b48c5bf4951cc359382ca7a2d55e374535a 100644
--- a/tests/src/mocks/openvr_mock.hpp
+++ b/tests/src/mocks/openvr_mock.hpp
@@ -36,7 +36,7 @@ SUPPRESS_WARNINGS_BEGIN
 #include "trompeloeil.hpp"
 SUPPRESS_WARNINGS_END
 
-#include "openvr_mock_export.hpp"
+#include "mocks/openvr_mock_export.hpp"
 
 using trompeloeil::_;
 
@@ -251,8 +251,6 @@ class OPENVR_MOCK_EXPORT IVRRenderModelsMock : public IVRRenderModels {
 
 }  // namespace vr
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class OPENVR_MOCK_EXPORT OpenVRMock {
  public:
   OpenVRMock()
@@ -357,8 +355,6 @@ class OPENVR_MOCK_EXPORT OpenVRMock {
   vr::IVRRenderModelsMock* ivr_render_models_mock_;
 };
 
-SUPPRESS_WARNINGS_END
-
 extern OPENVR_MOCK_EXPORT OpenVRMock openvr_mock;
 
 #define OPENVR_MOCK_ALLOW_ANY_CALL                                             \
diff --git a/tests/src/mocks/sdl_mock.cpp b/tests/src/mocks/sdl_mock.cpp
index 919ae46a7ece937b40f6c97ad5ccd936b21b35cb..3adf85769cb0e6a72a6723f7fbc1fce9e0bfc72f 100644
--- a/tests/src/mocks/sdl_mock.cpp
+++ b/tests/src/mocks/sdl_mock.cpp
@@ -33,8 +33,6 @@ SdlMock sdl_mock;
 #pragma clang diagnostic pop
 #endif
 
-extern template struct trompeloeil::reporter<trompeloeil::specialized>;
-
 extern "C" {
 int SDL_Init(Uint32 flags) { return sdl_mock.Get().SDL_Init(flags); }
 int SDL_InitSubSystem(Uint32 flags) {
diff --git a/tests/src/mocks/sdl_mock.hpp b/tests/src/mocks/sdl_mock.hpp
index c9146b5dda4c69339f0b10366da6f80b37acba15..10bfd11bf5a8f2b7d7d2e8231c1e53bbcaae68ef 100644
--- a/tests/src/mocks/sdl_mock.hpp
+++ b/tests/src/mocks/sdl_mock.hpp
@@ -31,7 +31,9 @@ SUPPRESS_WARNINGS_END
 
 #include "trompeloeil.hpp"
 
-class SdlMockInternal {
+#include "mocks/sdl_mock_export.hpp"
+
+class SDL_MOCK_EXPORT SdlMockInternal {
  public:
   MAKE_MOCK1(SDL_Init, int(Uint32 flags));  // NOLINT(readability/casting)
   MAKE_MOCK1(SDL_InitSubSystem,
@@ -55,7 +57,7 @@ class SdlMockInternal {
   MAKE_MOCK1(SDL_HideWindow, void(SDL_Window*));
 };
 
-class SdlMock {
+class SDL_MOCK_EXPORT SdlMock {
  public:
   SdlMock() : mock_(new SdlMockInternal) {}
   SdlMock(const SdlMock&) = delete;
@@ -72,7 +74,7 @@ class SdlMock {
   SdlMockInternal* mock_{nullptr};
 };
 
-extern SdlMock sdl_mock;
+extern SDL_MOCK_EXPORT SdlMock sdl_mock;
 
 #define SDL_MOCK_ALLOW_ANY_CALL                                              \
   ALLOW_CALL(sdl_mock.Get(), SDL_Init(SDL_INIT_VIDEO)).RETURN(0);            \
diff --git a/tests/src/test-transform.cpp b/tests/src/test-transform.cpp
index 4f844065e07dc3a97702f34d9cb4cef598eb9e11..38e66cf05e85e2e07bd72e61c4eb7c4a865e166f 100644
--- a/tests/src/test-transform.cpp
+++ b/tests/src/test-transform.cpp
@@ -266,58 +266,6 @@ SCENARIO(
 SCENARIO(
     "The transform component enables hierarchical arrangement of transforms.",
     "[phx][phx::Transform]") {
-  GIVEN("Two entities in a scene with transform components.") {
-    auto scene = std::make_shared<phx::Scene>();
-    auto entity1 = scene->CreateEntity();
-    auto entity2 = scene->CreateEntity();
-    phx::Transform* child = entity1->AddComponent<phx::Transform>();
-    phx::Transform* parent = entity2->AddComponent<phx::Transform>();
-
-    WHEN("We query the first transform's parent.") {
-      auto parent_ptr = child->GetParent();
-      THEN("It should be nullptr.") { REQUIRE(parent_ptr == nullptr); }
-    }
-
-    WHEN("We set the first transform's parent to the second.") {
-      child->SetParent(parent);
-
-      WHEN("We query the first transform's parent.") {
-        auto parent_ptr = child->GetParent();
-        THEN("It should equal the second transform.") {
-          REQUIRE(parent_ptr == parent);
-        }
-      }
-
-      WHEN("We query the second transform's child count.") {
-        auto child_count = parent->GetChildCount();
-        THEN("Its size should equal 1.") { REQUIRE(child_count == 1); }
-      }
-
-      WHEN("We query the second transform's first child.") {
-        auto child_ptr = parent->GetChild(0);
-        THEN("It should equal the first transform.") {
-          REQUIRE(child_ptr == child);
-        }
-      }
-
-      WHEN("We iterate the second transform's children.") {
-        auto iteration_count = 0;
-        for (auto it = parent->begin(); it != parent->end(); ++it)
-          iteration_count++;
-        THEN("It should consist of a single iteration.") {
-          REQUIRE(iteration_count == 1);
-        }
-      }
-
-      WHEN("We set the first transform's parent to nullptr.") {
-        child->SetParent(nullptr);
-        WHEN("We query the transform's parent.") {
-          auto parent_ptr = child->GetParent();
-          THEN("It should be nullptr.") { REQUIRE(parent_ptr == nullptr); }
-        }
-      }
-    }
-  }
   GIVEN("A hierarchy of transforms: A( B, C( D ) )") {
     auto scene = std::make_shared<phx::Scene>();
     auto entity1 = scene->CreateEntity();
diff --git a/tests/src/test_behavior_system.cpp b/tests/src/test_behavior_system.cpp
index d7ce2e41fd95c38264588fbf57f7614c612dd97a..3584faecc25b600396331f84b53e838953f55c77 100644
--- a/tests/src/test_behavior_system.cpp
+++ b/tests/src/test_behavior_system.cpp
@@ -21,15 +21,17 @@
 //------------------------------------------------------------------------------
 
 #include <memory>
-#include <vector>
 
 #include "catch/catch.hpp"
 #include "trompeloeil.hpp"
 
 #include "phx/core/engine.hpp"
+#include "phx/core/logger.hpp"
 #include "phx/core/scene.hpp"
 #include "phx/scripting/behavior.hpp"
 #include "phx/scripting/behavior_system.hpp"
+#include "phx/scripting/generic_behavior.hpp"
+#include "test_utilities/log_capture.hpp"
 
 extern template struct trompeloeil::reporter<trompeloeil::specialized>;
 
@@ -50,10 +52,11 @@ SCENARIO(
     auto scene = std::make_shared<phx::Scene>();
     engine.SetScene(scene);
     auto entity = scene->CreateEntity();
-    auto behavior = entity->AddComponent<BehaviorMock>();
 
-    WHEN("We create a behavior system.") {
-      auto behavior_system = engine.CreateSystem<phx::BehaviorSystem>();
+    auto behavior_system = engine.CreateSystem<phx::BehaviorSystem>();
+
+    WHEN("We create a mocked behavior") {
+      auto behavior = entity->AddComponent<BehaviorMock>();
       WHEN("We update the behavior system 10 times.") {
         REQUIRE_CALL(*behavior, OnUpdate()).TIMES(10);
         for (auto i = 0; i < 10; ++i)
@@ -62,3 +65,49 @@ SCENARIO(
     }
   }
 }
+SCENARIO("we can have generic behaviors", "[phx][phx::GenericBehavior]") {
+  GIVEN("An engine with a behavior system and an entity") {
+    phx::Engine engine;
+    auto scene = std::make_shared<phx::Scene>();
+    engine.SetScene(scene);
+    auto entity = scene->CreateEntity();
+    auto behavior_system = engine.CreateSystem<phx::BehaviorSystem>();
+
+    WHEN("We create a generic behavior") {
+      bool onConstructionCalled = false;
+      bool onUpdateCalled = false;
+      entity->AddComponent<phx::GenericBehavior>(
+          [&onConstructionCalled](phx::Entity*) {
+            onConstructionCalled = true;
+          },
+          [&onUpdateCalled](const phx::FrameTimer::TimeInfo*, phx::Entity*) {
+            onUpdateCalled = true;
+          });
+      THEN("onConstruction should be called, but no onUpdate yet") {
+        REQUIRE(onConstructionCalled);
+        REQUIRE_FALSE(onUpdateCalled);
+        WHEN("The behavior system is updated") {
+          behavior_system->Update(phx::FrameTimer::TimeInfo());
+          THEN("onUpdate is also called") {
+            REQUIRE(onConstructionCalled);
+            REQUIRE(onUpdateCalled);
+          }
+        }
+      }
+    }
+    WHEN("We we name a generic behavior") {
+      auto behavior = entity->AddComponent<phx::GenericBehavior>(
+          [](phx::Entity*) {},
+          [](const phx::FrameTimer::TimeInfo*, phx::Entity*) {}, "GenericName");
+      THEN("it is loggable") {
+        auto log_capture = std::make_shared<test_utilities::LogCapture>();
+        phx::logger =
+            std::make_shared<spdlog::logger>("logcapture", log_capture);
+        phx::logger->set_pattern("%v");
+
+        phx::info("{}", *behavior);
+        REQUIRE(*log_capture == "GenericBehavior: GenericName");
+      }
+    }
+  }
+}
diff --git a/tests/src/test_clear_pass.cpp b/tests/src/test_clear_pass.cpp
index 2a8322c1a6361b681b86398e5a18b4d0df0f2a40..dce48d4c421761b0d77d5e3b5f087f061f54d827 100644
--- a/tests/src/test_clear_pass.cpp
+++ b/tests/src/test_clear_pass.cpp
@@ -20,8 +20,6 @@
 // limitations under the License.
 //------------------------------------------------------------------------------
 
-#include "catch/catch.hpp"
-
 #include "phx/suppress_warnings.hpp"
 
 SUPPRESS_WARNINGS_BEGIN
@@ -31,11 +29,13 @@ SUPPRESS_WARNINGS_END
 
 #include "trompeloeil.hpp"
 
-#include "mocks/opengl_mock.hpp"
+#include "catch/catch.hpp"
 
 #include "phx/rendering/backend/render_target.hpp"
 #include "phx/rendering/render_passes/clear_pass.hpp"
 
+#include "mocks/opengl_mock.hpp"
+
 extern template struct trompeloeil::reporter<trompeloeil::specialized>;
 
 SCENARIO("The clear pass clears the active color and depth buffers.",
diff --git a/tests/src/test_hierarchical.cpp b/tests/src/test_hierarchical.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..30a8437b52c98be02d0898aa12c141d7df807aff
--- /dev/null
+++ b/tests/src/test_hierarchical.cpp
@@ -0,0 +1,97 @@
+//------------------------------------------------------------------------------
+// Project Phoenix
+//
+// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
+// Virtual Reality & Immersive Visualization Group.
+//------------------------------------------------------------------------------
+//                                 License
+//
+// Licensed under the 3-Clause BSD License (the "License");
+// you may not use this file except in compliance with the License.
+// See the file LICENSE for the full text.
+// You may obtain a copy of the License at
+//
+//     https://opensource.org/licenses/BSD-3-Clause
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//------------------------------------------------------------------------------
+
+#include <cstddef>
+
+#include <memory>
+
+#include "catch/catch.hpp"
+
+#include "phx/utility/aspects/hierarchical.hpp"
+
+class SomeHierarchical : public phx::Hierarchical<SomeHierarchical> {};
+
+SCENARIO("The hierarchical has parents and childs.",
+         "[phx][phx::Hierarchical]") {
+  GIVEN("Two hierarchical objects.") {
+    auto child = std::make_unique<SomeHierarchical>();
+    auto parent = std::make_unique<SomeHierarchical>();
+    WHEN("We query the first transform's parent.") {
+      auto parent_ptr = child->GetParent();
+      THEN("It should be nullptr.") { REQUIRE(parent_ptr == nullptr); }
+    }
+
+    WHEN("We set the first hierarchical's parent to the second.") {
+      child->SetParent(parent.get());
+
+      WHEN("We query the first hierarchical's parent.") {
+        auto parent_ptr = child->GetParent();
+        THEN("It should equal the second hierarchical.") {
+          REQUIRE(parent_ptr == parent.get());
+        }
+      }
+
+      WHEN("We query the second hierarchical's child count.") {
+        auto child_count = parent->GetChildCount();
+        THEN("Its size should equal 1.") { REQUIRE(child_count == 1); }
+      }
+
+      WHEN("We query the second hierarchical's first child.") {
+        auto child_ptr = parent->GetChild(0);
+        THEN("It should equal the first hierarchical.") {
+          REQUIRE(child_ptr == child.get());
+        }
+      }
+
+      WHEN("We iterate the second hierarchical's children.") {
+        auto iteration_count = 0;
+        for (auto it = parent->begin(); it != parent->end(); ++it)
+          iteration_count++;
+        THEN("It should consist of a single iteration.") {
+          REQUIRE(iteration_count == 1);
+        }
+      }
+
+      WHEN("We set the first hierarchical's parent to nullptr.") {
+        child->SetParent(nullptr);
+        WHEN("We query the hierarchical's parent.") {
+          auto parent_ptr = child->GetParent();
+          THEN("It should be nullptr.") { REQUIRE(parent_ptr == nullptr); }
+        }
+      }
+
+      WHEN("We destroy the child.") {
+        child.reset();
+        THEN("The parent has no more children.") {
+          REQUIRE(parent->GetChildCount() == 0);
+        }
+      }
+
+      WHEN("We destroy the parent.") {
+        parent.reset();
+        THEN("The child has no more parent.") {
+          REQUIRE(child->GetParent() == nullptr);
+        }
+      }
+    }
+  }
+}
diff --git a/tests/src/tests.cpp b/tests/src/tests.cpp
index 470c22fbbdaf5a1a78617debe061cf17ac89d6bb..ca1bc6a8bef06092ff36028073f3e64a8022b451 100644
--- a/tests/src/tests.cpp
+++ b/tests/src/tests.cpp
@@ -22,23 +22,3 @@
 
 #define CATCH_CONFIG_MAIN
 #include "catch/catch.hpp"
-
-#include "trompeloeil.hpp"
-
-namespace trompeloeil {
-template <>
-void reporter<specialized>::send(severity s, const char* file,  // NOLINT
-                                 unsigned long line,            // NOLINT
-                                 const char* msg) {             // NOLINT
-  std::ostringstream os;
-  if (line) os << file << ':' << line << '\n';
-  os << msg;
-  auto failure = os.str();
-  if (s == severity::fatal) {
-    FAIL(failure);
-  } else {
-    CAPTURE(failure);
-    CHECK(failure.empty());
-  }
-}
-}  // namespace trompeloeil
diff --git a/tests/test_utilities/approx.hpp b/tests/test_utilities/approx.hpp
index f09bbcaaba026bf7bad7ccfeaf8468dfe4ba3e1b..bfd3956d4824c5a64936d39a9ceb4c35922519c6 100644
--- a/tests/test_utilities/approx.hpp
+++ b/tests/test_utilities/approx.hpp
@@ -38,8 +38,6 @@ SUPPRESS_WARNINGS_END
 
 namespace test_utilities {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 template <typename T>
 class Approx {
  public:
@@ -76,8 +74,6 @@ class Approx {
   const T& value_;
 };
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace test_utilities
 
 namespace Catch {
diff --git a/tests/test_utilities/dummy_material_generator.hpp b/tests/test_utilities/dummy_material_generator.hpp
index 746df1f1d199b3887f8f26a600eeb20dfa6b71ab..41c449a466ce608d850c1f03d82a321cfb823c3e 100644
--- a/tests/test_utilities/dummy_material_generator.hpp
+++ b/tests/test_utilities/dummy_material_generator.hpp
@@ -45,7 +45,7 @@ class DummyMaterialGenerator : public ResourceLoadStrategy {
                          glm::vec3 ambient_color, float shininess);
   DummyMaterialGenerator(const DummyMaterialGenerator &) = default;
   DummyMaterialGenerator(DummyMaterialGenerator &&) = default;
-  ~DummyMaterialGenerator() = default;
+  ~DummyMaterialGenerator() override = default;
 
   DummyMaterialGenerator &operator=(const DummyMaterialGenerator &) = default;
   DummyMaterialGenerator &operator=(DummyMaterialGenerator &&) = default;
diff --git a/tests/test_utilities/dummy_mesh_generator.hpp b/tests/test_utilities/dummy_mesh_generator.hpp
index 49c73df2c9849330a259cd0883c07de04e87826c..5febf12190e0be8621034ef4bdb7cefeaab617a7 100644
--- a/tests/test_utilities/dummy_mesh_generator.hpp
+++ b/tests/test_utilities/dummy_mesh_generator.hpp
@@ -46,7 +46,7 @@ class DummyMeshLoader : public ResourceLoadStrategy {
                   std::vector<unsigned int> &&indices);
   DummyMeshLoader(const DummyMeshLoader &) = default;
   DummyMeshLoader(DummyMeshLoader &&) = default;
-  ~DummyMeshLoader() = default;
+  ~DummyMeshLoader() override = default;
 
   DummyMeshLoader &operator=(const DummyMeshLoader &) = default;
   DummyMeshLoader &operator=(DummyMeshLoader &&) = default;
diff --git a/tests/test_utilities/log_capture.hpp b/tests/test_utilities/log_capture.hpp
index ba70a17190eb1d0c9f1ba7da9b9cc2cea32457cf..aa0e5dddec6f8ee823877b6e032eafe98b81cf5b 100644
--- a/tests/test_utilities/log_capture.hpp
+++ b/tests/test_utilities/log_capture.hpp
@@ -34,8 +34,6 @@
 
 namespace test_utilities {
 
-SUPPRESS_WARNINGS_BEGIN_PADDED
-
 class LogCapture : public spdlog::sinks::sink {
  public:
   void log(const spdlog::details::log_msg& msg) override;
@@ -49,8 +47,6 @@ class LogCapture : public spdlog::sinks::sink {
   std::stringstream log_stream_;
 };
 
-SUPPRESS_WARNINGS_END
-
 }  // namespace test_utilities
 
 namespace Catch {