diff --git a/include/TestableMode.h b/include/TestableMode.h
index ddd64b40a5b64e11c03e5f3f1f7d270d3c67f341..e842ea28b76ce1075591f26677faf6f6424ec338 100644
--- a/include/TestableMode.h
+++ b/include/TestableMode.h
@@ -15,6 +15,10 @@
 #include <map>
 #include <mutex>
 
+namespace ChimeraTK {
+  class ConnectionMaker;
+}
+
 namespace ChimeraTK::detail {
   struct TestableMode {
     /** Special exception class which will be thrown if tests with the testable
@@ -68,7 +72,7 @@ namespace ChimeraTK::detail {
     /** Test if the testable mode mutex is locked by the current thread.
      *
      *  This function should generally not be used in user code. */
-    bool testLock();
+    [[nodiscard]] bool testLock() const;
 
     [[nodiscard]] bool canStep() const { return counter != 0; }
 
@@ -211,6 +215,9 @@ namespace ChimeraTK::detail {
      * output of the testable mode. Will return "*UNKNOWN_THREAD*" if the name for the given ID has not yet been set.
      */
     std::string threadName(const boost::thread::id& threadId = boost::this_thread::get_id());
+
+    bool _debugDecorating{false};
+    friend class ChimeraTK::ConnectionMaker;
   };
 
   /********************************************************************************************************************/
@@ -224,6 +231,11 @@ namespace ChimeraTK::detail {
       AccessorPair<T> other, const VariableNetworkNode& producer, const VariableNetworkNode& consumer) {
     if(not enabled) return other;
 
+    if(_debugDecorating) {
+      std::cout << "      Decorating pair " << producer.getQualifiedName() << "[" << other.first->getId() << "] -> "
+                << consumer.getQualifiedName() << "[" << other.second->getId() << "]" << std::endl;
+    }
+
     // create variable IDs
     size_t varId = detail::TestableMode::getNextVariableId();
     size_t varIdReturn;
@@ -264,6 +276,11 @@ namespace ChimeraTK::detail {
       return other;
     }
 
+    if(_debugDecorating) {
+      std::cout << "      Decorating single " << (direction == DecoratorType::READ ? "consumer " : "feeder ") << name
+                << "[" << other->getId() << "]" << std::endl;
+    }
+
     if(varId == 0) {
       varId = detail::TestableMode::getNextVariableId();
     }
diff --git a/src/ConnectionMaker.cc b/src/ConnectionMaker.cc
index fb71410a1713cbfafbfaf7cf64d10e2cb7647161..8a3479aeb92d202040c4c61f76351f17e4e3908c 100644
--- a/src/ConnectionMaker.cc
+++ b/src/ConnectionMaker.cc
@@ -121,6 +121,8 @@ namespace ChimeraTK {
   void ConnectionMaker::connect() {
     debug("Calling Connect...");
 
+    _app.getTestableMode()._debugDecorating = _debugConnections;
+
     debug("  Preparing trigger networks");
     debug("    Collecting triggers");
     std::set<Model::ProcessVariableProxy> triggers;
diff --git a/src/TestFacility.cc b/src/TestFacility.cc
index 93445b70ba45ecc4148503d80ded6fb25f391464..3b8f78487ad1171393814ebbee75fcd57e17907c 100644
--- a/src/TestFacility.cc
+++ b/src/TestFacility.cc
@@ -86,7 +86,7 @@ namespace ChimeraTK {
       for(auto& pv : pvManager->getAllProcessVariables()) {
         if(!pv->isReadable()) continue;
         callForTypeNoVoid(pv->getValueType(), [&](auto t) {
-          typedef decltype(t) UserType;
+          using UserType = decltype(t);
           this->getArray<UserType>(pv->getName()).readNonBlocking();
         });
       }
diff --git a/src/TestableMode.cc b/src/TestableMode.cc
index 8fb9fbf4c1d198d23ff6fa041fbc931dde23a247..9f51b8f133af6c76edbb07c4a1443f29b16c3770 100644
--- a/src/TestableMode.cc
+++ b/src/TestableMode.cc
@@ -27,13 +27,30 @@ namespace ChimeraTK::detail {
   }
   /*********************************************************************************************************************/
 
-  bool TestableMode::testLock() {
+  bool TestableMode::testLock() const {
     if(not enabled) return false;
     return getLockObject().owns_lock();
   }
 
   /*********************************************************************************************************************/
 
+  namespace {
+    /// This is a trick to make sure the exception is never caught, not even by the BOOST test framework.
+    void terminateTestStalled() {
+      struct TestStalled : std::exception {
+        [[nodiscard]] const char* what() const noexcept override { return "Test stalled."; }
+      };
+      try {
+        throw TestStalled();
+      }
+      catch(...) {
+        std::terminate();
+      }
+    }
+  } // namespace
+
+  /*********************************************************************************************************************/
+
   void TestableMode::lock(const std::string& name) {
     // don't do anything if testable mode is not enabled
     if(not enabled) return;
@@ -66,7 +83,7 @@ namespace ChimeraTK::detail {
                 << std::endl;                                                   // LCOV_EXCL_LINE
 
       // throw a specialised exception to make sure whoever catches it really knows what he does...
-      throw TestsStalled(); // LCOV_EXCL_LINE
+      terminateTestStalled(); // LCOV_EXCL_LINE
     }                       // LCOV_EXCL_LINE
 
     // check if the last owner of the mutex was this thread, which may be a hint
@@ -118,7 +135,7 @@ namespace ChimeraTK::detail {
         // Check for modules waiting for initial values (prints nothing if there are no such modules)
         Application::getInstance().circularDependencyDetector.printWaiters();
         // throw a specialised exception to make sure whoever catches it really knows what he does...
-        throw TestsStalled();
+        terminateTestStalled();
       }
     }
     else {