diff --git a/include/TestFacility.h b/include/TestFacility.h
index e37b48eb44e52bf38184c45b71a68e26ceb40094..789e35d3ba172368f7be2ff299e763bac4d876c2 100644
--- a/include/TestFacility.h
+++ b/include/TestFacility.h
@@ -35,12 +35,26 @@ namespace ChimeraTK {
       Application::getInstance().initialise();
     }
 
-    /** Start the application. This simply calls Application::run(). Since the
-     * application is in testable mode, it
-     *  will be ??? TODO define precisely what happens on start up */
+    /** Start the application in testable mode. */
     void runApplication() const {
+      // send default values for all control system variables
+      for(auto& pv : pvManager->getAllProcessVariables()) {
+        callForType(pv->getValueType(), [&pv, this](auto arg) {
+          if(!pv->isWriteable()) return;
+          typedef decltype(arg) T;
+          auto pv_casted = boost::dynamic_pointer_cast<NDRegisterAccessor<T>>(pv);
+          auto table = boost::fusion::at_key<T>(defaults.table);
+          if(table.find(pv->getName()) != table.end()) {
+            pv_casted->accessChannel(0) = table.at(pv->getName());
+          }
+          pv_casted->write();
+        });
+      }
+      // start the application
       Application::getInstance().run();
+      // set thread name
       Application::registerThread("TestThread");
+      // wait until all devices are opened
       Application::testableModeUnlock("waitDevicesToOpen");
       while(true) {
         boost::this_thread::yield();
@@ -166,6 +180,26 @@ namespace ChimeraTK {
       return acc;
     }
 
+    /** Set default value for scalar process variable. */
+    template<typename T>
+    void setScalarDefault(const ChimeraTK::RegisterPath& name, const T& value) {
+      std::vector<T> vv;
+      vv.push_back(value);
+      setArrayDefaults(name, vv);
+    }
+
+    /** Set default value for array process variable. */
+    template<typename T>
+    void setArrayDefault(const ChimeraTK::RegisterPath& name, const std::vector<T>& value) {
+      // check if PV exists
+      auto pv = pvManager->getProcessArray<T>(name);
+      if(pv == nullptr) {
+        throw ChimeraTK::logic_error("Process variable '" + name + "' does not exist.");
+      }
+      // store default value in map
+      boost::fusion::at_key<T>(defaults.table)[name] = value;
+    }
+
    protected:
     boost::shared_ptr<ControlSystemPVManager> pvManager;
 
@@ -182,6 +216,11 @@ namespace ChimeraTK {
     template<typename UserType>
     using ArrayMap = std::map<std::string, ChimeraTK::OneDRegisterAccessor<UserType>>;
     mutable ChimeraTK::TemplateUserTypeMap<ArrayMap> arrayMap;
+
+    // default values for process variables
+    template<typename UserType>
+    using Defaults = std::map<std::string, std::vector<UserType>>;
+    ChimeraTK::TemplateUserTypeMap<Defaults> defaults;
   };
 
 } /* namespace ChimeraTK */