diff --git a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py
index 3bc124216646f766ea7fd9686c397c8c4b80309b..3365f1475414d796f96ec68703f5c25440e7b2fa 100644
--- a/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py
+++ b/DaVinciExamples/python/DaVinciExamples/tupling/option_davinci_tupling_from_hlt2_gaudirun.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration           #
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -15,7 +15,7 @@ import Functors as F
 from FunTuple import FunctorCollection
 from FunTuple import FunTuple_Particles as Funtuple
 from PyConf.application import make_data_with_FetchDataFromFile
-from DaVinci.ConfigurationUpgrade import run_davinci_app
+from DaVinci.Configuration import run_davinci_app
 from DaVinci.reco_objects import make_pvs_for
 from DaVinci.algorithms import add_filter
 from DaVinci import options
diff --git a/DaVinciSys/scripts/davinci b/DaVinciSys/scripts/davinci
index 8277a839b192c357835da1c2af93cec193214aff..930e3b7226512ec9327272602b66ddc8b5303958 100755
--- a/DaVinciSys/scripts/davinci
+++ b/DaVinciSys/scripts/davinci
@@ -30,7 +30,7 @@ import os, sys, click
 from DaVinci.utilities_script import (dump_call, get_configurable_opts,
                                       set_testfiledb, create_inputdb_template,
                                       create_jobopt_template, get_dummy_config)
-from DaVinci.ConfigurationUpgrade import run_davinci_app
+from DaVinci.Configuration import run_davinci_app
 from DaVinci.config import options
 from DaVinci.optionChecker import log_click
 
diff --git a/DaVinciSys/tests/test_davinci_script.py b/DaVinciSys/tests/test_davinci_script.py
index 7be0a26397fbc61cf4c1ec934c0c21adbf9e17f4..cfe35640245c00d09b9c5448a4b211c37eab95fd 100644
--- a/DaVinciSys/tests/test_davinci_script.py
+++ b/DaVinciSys/tests/test_davinci_script.py
@@ -12,6 +12,12 @@
 import subprocess, os
 import pytest
 
+from pathlib import Path
+DIR = Path(__file__).parent.resolve()
+
+from unittest.mock import Mock, patch
+input_mock = Mock()
+
 
 def test_default():
     """
@@ -34,7 +40,8 @@ def test_override_job_option():
     Verify the overriding of a DaVinci option on the fly.
     No need to actually run the job, hence the dry run.
     """
-    cmd = 'davinci --export test_override_job_option.opts --dry-run run-mc --override_data_options --process "Turbo" --inputfiledb Upgrade_Bd2KstarMuMu -'
+    cmd = 'davinci --export test_override_job_option.opts --dry-run run-mc --override_data_options '\
+          ' --process "Turbo" --inputfiledb Upgrade_Bd2KstarMuMu -'
     result = subprocess.run(cmd, shell=True)
 
     # Just be maniac - the command should work ;-)
@@ -43,7 +50,6 @@ def test_override_job_option():
     # Inspect the produced .opts file and check for the option value overridden
     with open("test_override_job_option.opts") as f:
         assert any('.process = "Turbo";' in line for line in f.readlines())
-
     os.remove("test_override_job_option.opts")
 
 
@@ -54,7 +60,8 @@ def test_override_job_option_bis():
     (see related test "test_override_job_option").
     No need to actually run the job, hence the dry run.
     """
-    cmd = 'davinci --export test_override_job_option_bis.opts --dry-run run-mc  --process "Turbo" --override_data_options --inputfiledb Upgrade_Bd2KstarMuMu -'
+    cmd = 'davinci --export test_override_job_option_bis.opts --dry-run run-mc  --process "Turbo" '\
+          ' --override_data_options --inputfiledb Upgrade_Bd2KstarMuMu -'
     result = subprocess.run(cmd, shell=True)
 
     # Just be maniac - the command should work ;-)
@@ -69,8 +76,8 @@ def test_override_job_option_bis():
 
 def test_run_option_shortcut():
     """
-    Verify that the option values passed to the davinci command are accepted also 
-    when not using the full name (e.g. --inputfiledb ==> -i).
+    Verify that the option values passed to the davinci command are accepted 
+    also when not using the full name (e.g. --inputfiledb ==> -i).
     """
     cmd = 'davinci --dry-run -o test_run_option_shortcut.opts run-mc -i Upgrade_Bd2KstarMuMu -'
     result = subprocess.run(cmd, shell=True)
@@ -87,7 +94,8 @@ def test_run_option_shortcut():
 
 def test_create_options_templates():
     """
-    Verify that the 'create-options-templates' command produces a template for the inputfiledb and joboptfile option files.
+    Verify that the 'create-options-templates' command produces a template 
+    for the inputfiledb and joboptfile option files.
     """
     cmd = 'davinci create-options-templates -f test_inputdb_template.yaml test_jobopt_template.yaml'
     result = subprocess.run(cmd, shell=True)
@@ -96,12 +104,89 @@ def test_create_options_templates():
     assert result.returncode == 0
 
     import yaml
-    with open(
-            os.path.expandvars("test_inputdb_template.yaml")) as inputdb_file:
+    with open("test_inputdb_template.yaml") as inputdb_file:
         assert yaml.safe_load(inputdb_file)
 
-    with open(os.path.expandvars("test_jobopt_template.yaml")) as jobopt_file:
+    with open("test_jobopt_template.yaml") as jobopt_file:
         assert yaml.safe_load(jobopt_file)
 
     os.remove('test_inputdb_template.yaml')
     os.remove('test_jobopt_template.yaml')
+
+
+def test_create_template_interactively_changing_defaults(pytestconfig):
+    """
+    Verify that the interactive method of 'create-joboption-template' command produces
+    a correct job option template with the values defined by the user.
+    """
+    import yaml, os
+    from DaVinci.utilities_script import create_jobopt_template
+    from DaVinci.options_default import __optsDict__ as dv_defaults
+
+    #Changing some property values from the default for dumping the option file.
+    tmp_values = {"annsvc_config": "test_annsvc.tck.json"}
+
+    list_data_qualifiers = [
+        "data_type", "input_type", "simulation", "conddb_tag", "dddb_tag",
+        "input_files"
+    ]
+
+    list_of_args = []
+    for name, config in dv_defaults.items():
+        if name not in list_data_qualifiers:
+            val = tmp_values[name] if name in tmp_values else config["value"]
+            list_of_args.append(val)
+
+    input_mock.side_effect = list_of_args
+
+    def test_prompt_values():
+        with patch('builtins.input', input_mock):
+            create_jobopt_template(DIR / "test_jobopt_template.yaml", True)
+
+    capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')
+    capmanager.suspend_global_capture(in_=True)
+    test_prompt_values()
+    capmanager.resume_global_capture()
+
+    config = []
+    with open(DIR / "test_jobopt_template.yaml") as jobopt_file:
+        config = yaml.safe_load(jobopt_file)
+        assert isinstance(config, dict)
+    assert config["annsvc_config"] == "test_annsvc.tck.json"
+
+    os.remove(DIR / 'test_jobopt_template.yaml')
+    input_mock.reset_mock(return_value=True, side_effect=True)
+
+
+def test_create_template_interactively_with_defaults(pytestconfig):
+    """
+    Verify that the interactive method of 'create-joboption-template' command doesn't produce
+    a job option template if all the values are equal to the default ones.
+    """
+    import os
+    from DaVinci.utilities_script import create_jobopt_template
+    from DaVinci.options_default import __optsDict__ as dv_defaults
+
+    list_data_qualifiers = [
+        "data_type", "input_type", "simulation", "conddb_tag", "dddb_tag",
+        "input_files"
+    ]
+
+    list_of_args = []
+    for name, config in dv_defaults.items():
+        if name not in list_data_qualifiers:
+            list_of_args.append(config["value"])
+
+    input_mock.side_effect = list_of_args
+
+    def test_prompt_values():
+        with patch('builtins.input', input_mock):
+            create_jobopt_template(DIR / "test_jobopt_template.yaml", True)
+
+    capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')
+    capmanager.suspend_global_capture(in_=True)
+    test_prompt_values()
+    capmanager.resume_global_capture()
+
+    assert not os.path.exists(DIR / "test_jobopt_template.yaml")
+    input_mock.reset_mock(return_value=True, side_effect=True)
diff --git a/DaVinciTests/tests/options/option_davinci_gaudirun_job.py b/DaVinciTests/tests/options/option_davinci_gaudirun_job.py
index 86a491155688aa82380c12998e9e196fb61cc2f2..6f8b4dc45cf7c93cae2509aa93b55a82e4b64693 100644
--- a/DaVinciTests/tests/options/option_davinci_gaudirun_job.py
+++ b/DaVinciTests/tests/options/option_davinci_gaudirun_job.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -34,7 +34,7 @@ options.enable_unpack = False
 options.user_algorithms = "../options/option_davinci_gaudirun_job:main"
 options.write_fsr = False
 
-from DaVinci.ConfigurationUpgrade import run_davinci_app
+from DaVinci.Configuration import run_davinci_app
 fileDB_key = "Upgrade_Bd2KstarMuMu_ldst"
 fileDB_path = "$DAVINCIROOT/options/DaVinciDB-Example.yaml"
 run_davinci_app(fileDB_key, fileDB_path)
diff --git a/DaVinciTests/tests/options/prod_conf/options_reference.py b/DaVinciTests/tests/options/prod_conf/options_reference.py
index c9216b661ac620f0cf541df80c713b47a5e4b3e9..b00d02c0b82b4df9a2fc1931292af5c616031478 100644
--- a/DaVinciTests/tests/options/prod_conf/options_reference.py
+++ b/DaVinciTests/tests/options/prod_conf/options_reference.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -9,7 +9,7 @@
 # or submit itself to any jurisdiction.                                       #
 ###############################################################################
 from DaVinci import options
-from DaVinci.ConfigurationUpgrade import run_davinci_app
+from DaVinci.Configuration import run_davinci_app
 from DaVinci.compat.tests.params import prod_conf_params
 
 options.conddb_tag = prod_conf_params["CondDBTag"]
diff --git a/Phys/DaVinci/python/DaVinci/ConfigurationUpgrade.py b/Phys/DaVinci/python/DaVinci/Configuration.py
similarity index 92%
rename from Phys/DaVinci/python/DaVinci/ConfigurationUpgrade.py
rename to Phys/DaVinci/python/DaVinci/Configuration.py
index cb63e58f4190a9921fb744e07c45a33cf41be993..a108ba34815c1392a90968fac7a224bc8fb0daf2 100644
--- a/Phys/DaVinci/python/DaVinci/ConfigurationUpgrade.py
+++ b/Phys/DaVinci/python/DaVinci/Configuration.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2020-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -15,7 +15,8 @@ from PyConf.application import ComponentConfig, configure, configure_input
 from PyConf.Algorithms import EventAccounting
 from GaudiConf import reading
 from DaVinci.configOptions import (check_options, set_job_options,
-                                   set_args_options, set_input_file_options)
+                                   set_properties, set_args_options,
+                                   set_input_file_options)
 from DaVinci.algorithms import (setup_algorithms, define_fsr_writer,
                                 apply_filters_and_unpacking)
 from DaVinci.config import davinci_control_flow, prepare_davinci_nodes
@@ -57,6 +58,11 @@ def run_davinci_app(fileDB_key="",
     """
     from DaVinci import options
 
+    # Workaround ConfigurableUser limitation: options.<name> cannot be called if a value is not
+    # explicitely assigned and the related property is not set.
+    # Initialization in DVAppOptions class seems to be not sufficient.
+    set_properties(options)
+
     if fileDB_key and not prod_conf:
         set_input_file_options(options, fileDB_key, fileDB_file)
     if jobOpt_file:
diff --git a/Phys/DaVinci/python/DaVinci/algorithms.py b/Phys/DaVinci/python/DaVinci/algorithms.py
index 3b5940cf57007cecccd24893758c8cc17c619bb6..ca4ad5432e79b4cfa9a2373c477027429fa16da3 100644
--- a/Phys/DaVinci/python/DaVinci/algorithms.py
+++ b/Phys/DaVinci/python/DaVinci/algorithms.py
@@ -13,7 +13,6 @@ import os, sys, importlib
 from GaudiKernel.ProcessJobOptions import importOptions
 from PyConf.Algorithms import (LoKi__HDRFilter as HDRFilter, LoKi__VoidFilter
                                as VoidFilter)
-from DaVinci.configOptions import get_option_value
 from DaVinci.optionChecker import DVImportError, log_click
 
 
@@ -28,7 +27,7 @@ def setup_algorithms(options):
        - Dict of the algorithm instances to be run in the job.
        - List of public tool instances to configure.
     """
-    opts = get_option_value(options, "main_options")
+    opts = options.main_options
     publicTools = []
     dvAlgs = {}
 
@@ -39,7 +38,7 @@ def setup_algorithms(options):
             "INFO",
             "No MainOptions specified. DaVinci will import no options file!")
 
-    userAlgName = get_option_value(options, 'user_algorithms')
+    userAlgName = options.user_algorithms
     if not userAlgName:
         log_click(
             "WARNING",
@@ -51,9 +50,6 @@ def setup_algorithms(options):
         dvAlgs = {"UserAlgorithms": [VoidConsumer(OutputLevel=ERROR)]}
     else:
         userAlgs, publicTools = setup_user_algorithms(userAlgName)
-
-        if type(userAlgs) == list:
-            userAlgs = {"UserAlgorithms": userAlgs}
         dvAlgs.update(userAlgs)
 
     return dvAlgs, publicTools
@@ -148,7 +144,6 @@ def define_fsr_writer(options):
     Returns:
        - list of FSR algorithm instances to be configured.
     """
-    from Gaudi.Configuration import INFO
     from PyConf.Algorithms import GenFSRMerge, RecordStream
 
     algs = []
@@ -156,10 +151,7 @@ def define_fsr_writer(options):
         mergeGenfsr = GenFSRMerge(name="GenFSRMerge")
         algs.append(mergeGenfsr)
 
-    outputLevel = get_option_value(options, "output_level")
-    if outputLevel == '':
-        outputLevel = INFO
-
+    outputLevel = options.output_level
     recStream = RecordStream(
         name="FSROutputStreamDstWriter",
         OutputLevel=outputLevel,
@@ -201,10 +193,6 @@ def setup_user_algorithms(userAlgPath):
         modulePath = os.path.expandvars(modulePath)
         sys.path.append(modulePath)
 
-        _, ext = os.path.splitext(algName)
-        if ext == ".py":
-            algName = algName.rsplit('.', 1)[0]
-
         if ":" in algName:
             moduleName = algName.rsplit(":", 1)[0]
             funcName = ".%s" % algName.rsplit(":", 1)[1]
@@ -212,6 +200,10 @@ def setup_user_algorithms(userAlgPath):
             moduleName = algName
             funcName = ""
 
+        _, ext = os.path.splitext(moduleName)
+        if ext == ".py":
+            moduleName = moduleName.rsplit('.', 1)[0]
+
         # Import the module containing the user algorithms
         try:
             module = importlib.import_module(moduleName)  # noqa: F841
@@ -252,8 +244,8 @@ def unpack_locations(options, unpack_only_mc):
     """
     from GaudiConf import reading
 
-    process = get_option_value(options, "process")
-    stream = get_option_value(options, "stream")
+    process = options.process
+    stream = options.stream
 
     unpack_raw_event = reading.unpack_rawevent(
         bank_types=['ODIN', 'DstData', 'HltDecReports'],
@@ -296,8 +288,8 @@ def get_hlt_reports(options, source=''):
     """
     from GaudiConf import reading
 
-    process = get_option_value(options, "process")
-    stream = get_option_value(options, "stream")
+    process = options.process
+    stream = options.stream
 
     if source == 'Hlt2':
         dec_reports = reading.hlt2_decisions(
diff --git a/Phys/DaVinci/python/DaVinci/compat/DaVinciConf.py b/Phys/DaVinci/python/DaVinci/compat/DaVinciConf.py
index a15afd165a2147af54e8832e691827fa2546e472..922081b15c4162b831e1c6c39da5e0c6430f5140 100644
--- a/Phys/DaVinci/python/DaVinci/compat/DaVinciConf.py
+++ b/Phys/DaVinci/python/DaVinci/compat/DaVinciConf.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -15,7 +15,7 @@ import re
 from Gaudi.Configuration import appendPostConfigAction
 from Configurables import (LHCbApp, EventSelector, DDDBConf, CondDB,
                            LHCbConfigurableUser, HistogramPersistencySvc)
-from DaVinci.ConfigurationUpgrade import run_davinci_app
+from DaVinci.Configuration import run_davinci_app
 from DaVinci.configOptions import set_option_value
 from DaVinci import options
 
diff --git a/Phys/DaVinci/python/DaVinci/configOptions.py b/Phys/DaVinci/python/DaVinci/configOptions.py
index 61eab8e03a5a41bd8080930b903722dcf0761a4b..fcab94fc12f9f6c82f66354e81c8b683b27a50b5 100644
--- a/Phys/DaVinci/python/DaVinci/configOptions.py
+++ b/Phys/DaVinci/python/DaVinci/configOptions.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2020-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -17,20 +17,6 @@ from DaVinci.optionChecker import DVOptionError, DVRuntimeError
 from DaVinci.optionChecker import option_checker, log_click
 
 
-def get_option_value(options, name):
-    """
-    Get option value for a given name.
-
-    Args:
-       - options: list of DaVinci options.
-       - name: name of the option to be retrieved.
-
-    Returns:
-       - Value of the option of interest.
-    """
-    return options.getProp(name)
-
-
 def set_option_value(options, name, value):
     """
     Set option value for a given name.
@@ -104,7 +90,8 @@ def set_input_file_options(options, fileDB_key, fileDB_file):
                     set_option_value(options, "input_files", obj)
 
 
-def set_job_options(options, jobOptFile, fileDB_key, fileDB_file, override_data_options):
+def set_job_options(options, jobOptFile, fileDB_key, fileDB_file,
+                    override_data_options):
     """
     Set the job properties required by the user. The method checks if there
     are options related to the input files selected with key and file of the
@@ -117,31 +104,29 @@ def set_job_options(options, jobOptFile, fileDB_key, fileDB_file, override_data_
        - fileDB_file: file containing the testfileDB.
        - override_data_options: boolean for enabling data options override.
     """
-    if jobOptFile == '':
-        log_click("WARNING",
-                  "No jobOption file selected, the default values are used.")
-    else:
-        dataOptions = list_data_options(fileDB_key.split(":")[0], fileDB_file)
-
-        with open(os.path.expandvars(jobOptFile)) as config_file:
-            _, ext = os.path.splitext(jobOptFile)
-            if ext in (".yaml", ".yml", ".json"):
-                import yaml
-                config = yaml.safe_load(config_file)
-            elif ext == '.py':
-                import ast
-                config = ast.literal_eval(config_file.read())
-            else:
-                raise ValueError(
-                    'JobOption file extension not known! Please use only a .py, .json or .yaml (.yml) file!'
-                )
-
-            for key, value in config.items():
-                if is_option_settable(options, key, dataOptions, override_data_options):
-                    set_option_value(options, key, value)
-
-
-def set_args_options(options, ctx_args, fileDB_key, fileDB_file, override_data_options):
+    dataOptions = list_data_options(fileDB_key.split(":")[0], fileDB_file)
+
+    with open(os.path.expandvars(jobOptFile)) as config_file:
+        _, ext = os.path.splitext(jobOptFile)
+        if ext in (".yaml", ".yml", ".json"):
+            import yaml
+            config = yaml.safe_load(config_file)
+        elif ext == '.py':
+            import ast
+            config = ast.literal_eval(config_file.read())
+        else:
+            raise ValueError(
+                'JobOption file extension not known! Please use only a .py, .json or .yaml (.yml) file!'
+            )
+
+        for key, value in config.items():
+            if is_option_settable(options, key, dataOptions,
+                                  override_data_options):
+                set_option_value(options, key, value)
+
+
+def set_args_options(options, ctx_args, fileDB_key, fileDB_file,
+                     override_data_options):
     """
     Set the extra arguments required by the user.
 
@@ -159,7 +144,8 @@ def set_args_options(options, ctx_args, fileDB_key, fileDB_file, override_data_o
         key = ctx_args[i][2:]
         value = ctx_args[i + 1]
 
-        if is_option_settable(options, key, dataOptions, override_data_options):
+        if is_option_settable(options, key, dataOptions,
+                              override_data_options):
             set_option_value(options, key, value)
 
 
@@ -230,33 +216,39 @@ def check_options(options):
     Args:
        - options: list of DaVinci options.
     """
-    dataType = get_option_value(options, "data_type")
+    dataType = options.data_type
     option_checker("data_type", dataType)
 
-    inputType = get_option_value(options, "input_type").upper()
+    inputType = (options.input_type).upper()
     option_checker("input_type", inputType)
     if inputType != "MDF":
         set_option_value(options, "input_type", "ROOT")
 
-    flagMC = get_option_value(options, "simulation")
+    flagMC = options.simulation
     if not flagMC:
-        if get_option_value(options, "merge_genfsr"):
+        if options.merge_genfsr:
             raise DVRuntimeError(
                 "merge_genfsr", "simulation",
                 "GenFSR are not available in real data so merge_genfsr cannot be run! Set merge_genfsr = False."
             )
     else:
-        if get_option_value(options, "lumi"):
+        if options.lumi:
             raise DVRuntimeError(
                 "Lumi", "simulation",
                 "Lumi not valid for simulation! Set lumi = False.")
 
         ## for simulation, it is very important to specify proper DB-tags:
-        if not get_option_value(options, 'dddb_tag'):
+        if not options.dddb_tag:
             raise DVOptionError(
                 "dddb_tag",
                 "``dddb_tag''   is not specified for simulated data!")
-        if not get_option_value(options, 'conddb_tag'):
+        if not options.conddb_tag:
             raise DVOptionError(
                 "conddb_tag",
                 "``conddb_tag'' is not specified for simulated data!")
+
+
+def set_properties(options):
+    for name, default in options.getDefaultProperties().items():
+        if not options.isPropertySet(name):
+            options.setProp(name, default)
diff --git a/Phys/DaVinci/python/DaVinci/optionChecker.py b/Phys/DaVinci/python/DaVinci/optionChecker.py
index 71e8e4398a7cf80a9f9b58f48c8c88b2400fe76d..d52165800fa30e40fe2dc123b909adcf98b84354 100644
--- a/Phys/DaVinci/python/DaVinci/optionChecker.py
+++ b/Phys/DaVinci/python/DaVinci/optionChecker.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2020-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -11,6 +11,7 @@
 """
 Define value and run-time errors used in DaVinci application.
 """
+import click
 
 
 class DVOptionError(ValueError):
@@ -28,7 +29,7 @@ class DVOptionError(ValueError):
         """
         String representation.
         """
-        return (set_color("red") + self.message + set_color("plain"))
+        return f"{click.style('DVOptionError', bold=True, fg='red')} {click.style(self.message, fg='red')}"
 
 
 class DVRuntimeError(RuntimeError):
@@ -46,7 +47,7 @@ class DVRuntimeError(RuntimeError):
         """
         String representation.
         """
-        return (set_color("red") + self.message + set_color("plain"))
+        return f"{click.style('DVRuntimeError', bold=True, fg='red')} {click.style(self.message, fg='red')}"
 
 
 class DVImportError(ImportError):
@@ -64,24 +65,48 @@ class DVImportError(ImportError):
         """
         String representation.
         """
-        return (set_color("red") + self.message + set_color("plain"))
+        return f"{click.style('DVImportError', bold=True, fg='red')} {click.style(self.message, fg='red')}"
+
+
+class DVKeyError(KeyError):
+    """
+    DaVinci exception class for accessing to an invalid key option.
+    """
+
+    def __init__(self, optName):
+        """
+        Constructor.
+        """
+        self.message = f"There is no option named {optName} in DaVinci!"
+
+    def __str__(self):
+        """
+        String representation.
+        """
+        return f"{click.style('DVKeyError', bold=True, fg='red')} {click.style(self.message, fg='red')}"
 
 
 def option_checker(name, value):
     """
     Check the correctness of a DaVinci configurable option.
     """
-    try:
-        allowedValues = get_allowed_option_values()
-        if value not in allowedValues[name]:
-            print_allowed_option_values(allowedValues, name)
-            raise DVOptionError(name, value)
-    except KeyError:
-        print(
-            set_color("red") +
-            f"You are trying to check the unknown option {name}!" +
-            set_color("plain"))
-        print_allowed_option_values()
+    from DaVinci.options_default import __optsDict__ as dv_default
+
+    allowedValues = get_allowed_option_values()
+    if name in dv_default.keys() and name not in allowedValues.keys():
+        log_click(
+            "INFO",
+            f"The option {name} has no restrinctions on the allowed values.")
+    else:
+        try:
+            if value not in allowedValues[name]:
+                print_allowed_option_values(allowedValues, name)
+                raise DVOptionError(name, value)
+        except KeyError:
+            log_click("ERROR",
+                      f"You are trying to check the unknown option {name}!")
+            print_allowed_option_values(allowedValues)
+            raise DVKeyError(name)
 
 
 def get_allowed_option_values():
@@ -96,7 +121,6 @@ def get_allowed_option_values():
             "ROOT", "XGEN"
         ]
     }
-
     return allowedValues
 
 
@@ -105,29 +129,24 @@ def print_allowed_option_values(allowedValues, name=None):
     Print the allowed values for the DaVinci option configurations.
     """
     if name is None:
-        print(
-            set_color("green") +
-            "Known job option configurations and allowed values:")
-        for name, values in allowedValues.iteritems():
-            print(f"{name} \t : {values}", set_color("plain"))
+        log_click("", "Known job option configurations and allowed values:",
+                  "green")
+        for name, values in allowedValues.items():
+            log_click("", f"{name} \t : {values}")
     else:
-        print(
-            set_color("green") + f"Allowed values for DaVinci option {name}:")
-        print(allowedValues[name], set_color("plain"))
+        log_click("", f"Allowed values for DaVinci option {name}:", "green")
+        log_click("", f"{allowedValues[name]}")
 
 
-def set_color(key):
-    colors = {
-        "plain": "\x1b[00m",
-        "red": "\x1b[01;31m",
-        "green": "\x1b[01;32m"
-    }
-
-    return colors[key]
-
-
-def log_click(mode, message):
+def log_click(mode, message, color_text="white"):
     import click
-    colors = {"INFO": "blue", "WARNING": "yellow", "ERROR": "red"}
+    config_colors = {
+        "INFO": "blue",
+        "WARNING": "yellow",
+        "ERROR": "red",
+    }
 
-    click.echo(f"{click.style(mode, bold=True, fg=colors[mode])} {message}")
+    color_mode = config_colors[mode] if mode else "white"
+    click.echo(
+        f"{click.style(mode, bold=True, fg=color_mode)} {click.style(message, fg=color_text)}"
+    )
diff --git a/Phys/DaVinci/tests/config/test_DVAppOptions.py b/Phys/DaVinci/tests/config/test_DVAppOptions.py
index ad75df5673f010f310bb01feaa3b650743261e4c..d3e321b31bdc152c243e33332579089d776de6f8 100644
--- a/Phys/DaVinci/tests/config/test_DVAppOptions.py
+++ b/Phys/DaVinci/tests/config/test_DVAppOptions.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -8,27 +8,37 @@
 # granted to it by virtue of its status as an Intergovernmental Organization  #
 # or submit itself to any jurisdiction.                                       #
 ###############################################################################
-
 import pytest
-
 from DaVinci import options
 
 
 def test_option_set():
+    """
+    Check if it's possible to access directly to an option if set.
+    """
     print(options.detectors)
 
 
 def test_option_unset():
+    """
+    Check that it's impossible to access to an option if it has not been set.
+    """
     with pytest.raises(AttributeError):
         print(options.evt_max)
 
 
 def test_option_get_after_set():
+    """
+    Check that after assigning a value the option can be accessed correctly.
+    """
     options.evt_max = 1
     print(options.evt_max)
 
 
 def test_option_unknown():
+    """
+    Check that it's impossible to access to an unknow option.
+    """
     with pytest.raises(AttributeError):
         print(options.unknown)
 
@@ -40,10 +50,8 @@ def test_ApplicationOptions_consistency_with_PyConf():
     from PyConf.application import ApplicationOptions
     from DaVinci import options
     from DaVinci.options_default import __optsDict__ as dv_defaults
-
     lhcb_options = ApplicationOptions.getDefaultProperties()
     dv_options = options.getDefaultProperties()
-
     for name, _ in lhcb_options.items():
         # Exclude Moore-specific options since they will be moved into a
         # dedicated Moore-specific ApplicationOptions class.
diff --git a/Phys/DaVinci/tests/config/test_algorithms.py b/Phys/DaVinci/tests/config/test_algorithms.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c70d7355c45f821ada7ed82ad6086c1ba777e30
--- /dev/null
+++ b/Phys/DaVinci/tests/config/test_algorithms.py
@@ -0,0 +1,269 @@
+###############################################################################
+# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration           #
+#                                                                             #
+# This software is distributed under the terms of the GNU General Public      #
+# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
+#                                                                             #
+# In applying this licence, CERN does not waive the privileges and immunities #
+# granted to it by virtue of its status as an Intergovernmental Organization  #
+# or submit itself to any jurisdiction.                                       #
+###############################################################################
+import pytest, os
+from PyConf.Algorithms import Gaudi__Examples__VoidConsumer as VoidConsumer
+from DaVinci import options
+from DaVinci.optionChecker import DVImportError
+from DaVinci.algorithms import (setup_algorithms, define_fsr_writer,
+                                add_filter, apply_filters_and_unpacking,
+                                setup_user_algorithms, unpack_locations,
+                                ConfiguredFuntuple)
+
+
+def test_import_main_options():
+    """
+    Check if a configurable .opts file can be imported correctly in DaVinci.
+    """
+    filename = "test_options.opts"
+    with open(filename, "w") as f:
+        f.write("DVAppOptions.enable_unpack = True;\n")
+        f.write("DVAppOptions.evt_max = 5;\n")
+        f.close()
+
+    options.main_options = filename
+    options.user_algorithms = ""
+    setup_algorithms(options)
+    os.remove(filename)
+
+    # Restore default value avoid failure in the next tests
+    options.main_options = ""
+
+
+def test_set_user_algorithms():
+    """
+    Check if DaVinci can import correctly an external user algorithm implemented in a given python module.
+    """
+    filename = "test_useralgs"
+    with open(f"{filename}.py", "w") as f:
+        f.write("""
+from PyConf.Algorithms import Gaudi__Examples__VoidConsumer as VoidConsumer
+from DaVinci import options
+
+options.data_type = 'Upgrade'
+options.enable_unpack = False
+options.evt_max = 10
+
+def main():
+    algs = {'testAlg': [VoidConsumer()]}
+    return algs, []
+""")
+        f.close()
+
+    options.user_algorithms = f"{filename}:main"
+    test_algs, _ = setup_algorithms(options)
+    assert "testAlg" in test_algs
+    os.remove(f"{filename}.py")
+
+    # Restore default value avoid failure in the next tests
+    options.user_algorithms = ""
+
+
+def test_no_user_algorithms():
+    """
+    Check that no algorithms are imported if user doens't provide a python module.
+    """
+    test_algs, _ = setup_user_algorithms("")
+    assert len(test_algs) == 0
+
+
+def test_user_algorithms_with_ext():
+    """
+    Check that a python module can be imported correcty 
+    even if the '.py' extension is passed by mistake from the user.
+    """
+    filename = "./test_useralg.py"
+    with open(filename, "w") as f:
+        f.write("""
+from PyConf.Algorithms import Gaudi__Examples__VoidConsumer as VoidConsumer
+from DaVinci import options
+
+options.data_type = 'Upgrade'
+options.enable_unpack = False
+options.evt_max = 10
+
+def main():
+    algs = [VoidConsumer()]
+    return algs, []
+""")
+    f.close()
+
+    test_algs, _ = setup_user_algorithms(f"{filename}:main")
+    assert "UserAlgorithms" in test_algs
+    os.remove(filename)
+
+
+def test_user_algorithms_no_module():
+    """
+    Check DaVinci returns the correct error if the python module define by the user doesn't exist.
+    """
+    filename = "test_useralg.py"
+    with pytest.raises((TypeError, DVImportError)):
+        test_algs, _ = setup_user_algorithms(filename)
+
+
+def test_user_algorithms_no_function():
+    """
+    Check DaVinci returns the correct error if the user provide only the module 
+    and not the name of the function to be run.
+    """
+    filename = "test_useralg"
+    with open(f"{filename}.py", "w") as f:
+        f.write("""
+rom PyConf.Algorithms import Gaudi__Examples__VoidConsumer as VoidConsumer
+from DaVinci import options
+
+options.data_type = 'Upgrade'
+options.enable_unpack = False
+options.evt_max = 10
+""")
+    f.close()
+
+    with pytest.raises((TypeError, DVImportError)):
+        test_algs, _ = setup_user_algorithms(filename)
+    os.remove(f"{filename}.py")
+
+
+def test_user_algorithms_wrong_function():
+    """
+    Check DaVinci returns the correct error if the function specified by the user doesn't exist. 
+    """
+    filename = "test_useralg"
+    with open(f"{filename}.py", "w") as f:
+        f.write("""
+from PyConf.Algorithms import Gaudi__Examples__VoidConsumer as VoidConsumer
+from DaVinci import options
+
+options.data_type = 'Upgrade'
+options.enable_unpack = False
+options.evt_max = 10
+
+def main():
+    algs = {'testAlg': [VoidConsumer()]}
+    return algs, []
+""")
+    f.close()
+
+    with pytest.raises((AttributeError, DVImportError)):
+        test_algs, _ = setup_user_algorithms(f"{filename}:main2")
+    os.remove(f"{filename}.py")
+
+
+def test_define_write_fsr():
+    """
+    Check if DaVinci import correctly the algorithm to merge and write FSRs.
+    """
+    options.output_level = 3
+    options.merge_genfsr = True
+    options.simulation = True
+    test_algs = define_fsr_writer(options)
+    assert any("GenFSRMerge" == x.name for x in test_algs)
+
+
+def test_add_hlt2_filter():
+    """
+    Check if DaVinci is able to implement correctly a fliter to a Hlt2 line.
+    """
+    options.process = "Hlt2"
+    options.stream = "default"
+    test_filter = add_filter("test_filter", "HLT_PASS('Hlt2TESTLineDecision')")
+    assert "HDRFilter" in test_filter.fullname
+
+
+def test_add_spruce_filter():
+    """
+    Check if DaVinci is able to implement correctly a fliter to a Sprucing line.
+    """
+    options.process = "Spruce"
+    options.stream = "default"
+    test_filter = add_filter("test_filter",
+                             "HLT_PASS('SpruceTESTLineDecision')")
+    assert "HDRFilter" in test_filter.fullname
+
+
+def test_add_void_filter():
+    """
+    Check if DaVinci is able to implement correcty a Void filter 
+    if 'HLT_PASS' string is not found in the filter code."
+    """
+    test_filter = add_filter("test_filter", "VOIDTEST_Filter")
+    assert "VoidFilter" in test_filter.fullname
+
+
+def test_unpack_locations():
+    """
+    Check if the unpacking algorithms are retrieved correctly from GaudiConf.
+    TO BE REMOVED WHEN THE UNPACKING WILL BECOME FULLY FUNCTIONAL.
+    """
+    options.simulation = True
+    test_algs = unpack_locations(options, False)
+
+    assert isinstance(test_algs, list)
+    assert any("Unpack" in alg.fullname for alg in test_algs)
+
+
+def test_unpack_locations_xgen():
+    """
+    Check if DaVinci unpacks only the MC locations if run on an xgen file.
+    (i.e. 'unpack_only_mc' is set to True.)
+    TO BE REMOVED WHEN THE UNPACKING WILL BECOME FULLY FUNCTIONAL.
+    """
+    options.simulation = True
+    unpack_only_mc = True
+    test_algs = unpack_locations(options, unpack_only_mc)
+
+    assert isinstance(test_algs, list)
+    assert any("UnpackMCParticle" in alg.fullname for alg in test_algs)
+    assert not any("UnpackTrack" in alg.fullname for alg in test_algs)
+
+
+def test_apply_filters_and_unpack():
+    """
+    Check if DaVinci applies correctly a filter in front of a given algorithm
+    and instantiates correctly the main unpacking algorithms.
+    TO BE UPDATED WHEN THE UNPACKING WILL BECOME FULLY FUNCTIONAL.
+    """
+    options.evt_pre_filters = {"test_filter": "EVT_PREFILTER"}
+    options.enable_unpack = True
+    alg_dict = {"test_alg": [VoidConsumer()]}
+    test_alg_dict = apply_filters_and_unpacking(options, alg_dict, False)
+    list_of_main_expected_algs = [
+        "LoKi__VoidFilter", "LHCb__UnpackRawEvent", "HltPackedDataDecoder",
+        "UnpackMCParticle", "UnpackTrack"
+    ]
+
+    for exp_alg in list_of_main_expected_algs:
+        assert any(
+            exp_alg in alg.fullname for alg in test_alg_dict["test_alg"])
+
+
+def test_configured_funtuple():
+    """
+    Check if the ConfiguredFuntuple provides a correct instance of FunTuple.
+    """
+    from FunTuple import FunctorCollection
+    from FunTuple.functorcollections import Kinematics
+    branches = {'B0': "[B0 -> D_s- pi+]CC"}
+    variables = {'B0': FunctorCollection(Kinematics)}
+    config = {
+        "TestTuple": {
+            "location": "/Event/Spruce/SpruceTestLine/Particles",
+            "filters":
+            ["HLT_PASS('SpruceTestLine1Decision')", "VoidTest_Filter"],
+            "preamble": ['TRACK_MAX_PT = MAXTREE(ISBASIC & HASTRACK, PT, -1)'],
+            "tree": "DecayTree",
+            "branches": branches,
+            "variables": variables,
+        }
+    }
+
+    test_dict = ConfiguredFuntuple(config)
+    assert any("FunTupleBase_Particles/Tuple_TestTuple" in alg.fullname
+               for alg in test_dict["TestTuple"])
diff --git a/Phys/DaVinci/tests/config/test_configOptions.py b/Phys/DaVinci/tests/config/test_configOptions.py
index ca07b39c6b8492fc7f92848794bfabf648b76493..4ed69482b1aa51165731f75c544a4c4bbc2a1f01 100644
--- a/Phys/DaVinci/tests/config/test_configOptions.py
+++ b/Phys/DaVinci/tests/config/test_configOptions.py
@@ -1,5 +1,5 @@
-##############################################################################
-# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+###############################################################################
+# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -11,19 +11,211 @@
 
 import pytest
 
-from DaVinci.configOptions import list_data_options
+from DaVinci.optionChecker import DVOptionError, DVRuntimeError
+from DaVinci.configOptions import (list_data_options, set_option_value,
+                                   set_input_file_options, set_job_options,
+                                   check_options, is_option_settable)
+from DaVinci import options
+from pathlib import Path
+DIR = Path(__file__).parent.resolve()
+
+fileDB_file = DIR / "../../options/DaVinciDB-Example.yaml"
+fileDB_key = "Upgrade_Bd2KstarMuMu_ldst"
+fileDB = "TestFileDB"
+jobOpt_file = DIR / "../../options/jobOptions-Example"
 
 
 def test_list_data_options_key_in_TestFileDB():
-    fileDB_key = "Upgrade_Bd2KstarMuMu"
-    fileDB_file = "TestFileDB"
-    assert list_data_options(fileDB_key, fileDB_file) == [
+    """
+    Check if the list of data options in TestFileDB matches the one expected by DaVinci.
+    """
+    key = "Upgrade_Bd2KstarMuMu"
+    assert list_data_options(key, fileDB) == [
         'Author', 'Format', 'DataType', 'Date', 'Simulation', 'CondDB', 'DDDB'
     ]
 
 
+def test_list_data_options_key_in_userDB():
+    """
+    Check if the list of data options in a TestFileDB-like file prepared as example is updated.
+    """
+    assert list_data_options(fileDB_key, fileDB_file) == [
+        'data_type', 'input_type', 'simulation', 'conddb_tag', 'dddb_tag'
+    ]
+
+
 def test_list_data_options_unknown_key_in_TestFileDB():
+    """
+    Check if DaVinci returns an error if the key used for the TestFileDB is unknown.
+    """
     with pytest.raises(KeyError):
-        fileDB_key = "UnknownKey"
-        fileDB_file = "TestFileDB"
-        _ = list_data_options(fileDB_key, fileDB_file)
+        key = "UnknownKey"
+        _ = list_data_options(key, fileDB)
+
+
+def test_handle_options():
+    """
+    Check if DaVinci is able to set correctly the value of a given option.
+    """
+    opt_name = "ntuple_file"
+    opt_value = "ntupleDV_test.root"
+    set_option_value(options, opt_name, opt_value)
+    assert options.getProp(opt_name) == opt_value
+
+
+def test_option_correct_str2bool_conversion():
+    """
+    Check if DaVinci converts correctly the value of a boolean option even if the value is passed as string.
+    """
+    opt_name = "enable_unpack"
+    opt_value = "True"
+    set_option_value(options, opt_name, opt_value)
+    assert options.getProp(opt_name)
+
+
+def test_option_wrong_str2bool_conversion():
+    """
+    Check if DaVinci raises an error if the string-to-bool conversion is applied on a generic string content.
+    """
+    opt_name = "enable_unpack"
+    opt_value = "unknown_value"
+    with pytest.raises(DVOptionError):
+        set_option_value(options, opt_name, opt_value)
+
+
+def test_set_input_file_from_TestFileDB():
+    """
+    Check if DaVinci is able to set correctly input data options given a key and the TestFileDB.
+    """
+    key = "Upgrade_Bd2KstarMuMu"
+    set_input_file_options(options, key, fileDB)
+    assert not options.input_files == []
+
+
+def test_set_input_file_from_userDB():
+    """
+    Check if DaVinci is able to set correctly input data options 
+    given a key and TestFileDB-like file database defined by the user.
+    """
+    set_input_file_options(options, fileDB_key, fileDB_file)
+    assert not options.input_files == []
+
+
+def test_select_input_file_by_index():
+    """
+    Check if DaVinci selects only a specific file from the ones listed in the database
+    if the file index is provided after the database key.
+    """
+    key = f"{fileDB_key}:3"
+    set_input_file_options(options, key, fileDB_file)
+    assert len(options.input_files) == 1
+
+
+def test_wrong_input_file_index():
+    """
+    Check that DaVinci raises an error if the file index is higher than the number of 
+    input files available in the TestFileDB-like database.
+    """
+    key = f"{fileDB_key}:100"
+    with pytest.raises(ValueError):
+        set_input_file_options(options, key, fileDB_file)
+
+
+def test_job_options_from_py_file():
+    """
+    Check if DaVinci sets correctly an option value when reading a .py job option file.
+    Check also the .py example is well formatted and readable by DaVinci.
+    """
+    set_job_options(options, f"{jobOpt_file}.py", "", "", False)
+    assert options.evt_max == 100
+
+
+def test_job_options_from_yaml_file():
+    """
+    Check if DaVinci sets correctly an option value when reading a .yaml job option file.
+    Check also the .yaml example is well formatted and readable by DaVinci.
+    """
+    set_job_options(options, f"{jobOpt_file}.yaml", "", "", False)
+    assert options.evt_max == 100
+
+
+def test_job_options_from_unknown_file():
+    """
+    Check that DaVinci raises an error if the job option file passed by the user doesn't exist.
+    """
+    import os
+    job_opt_name = "test_job_options.txt"
+    with open(job_opt_name, "w") as f:
+        f.write("evt_max: 100")
+        f.close()
+    with pytest.raises(ValueError):
+        set_job_options(options, job_opt_name, "", "", False)
+    os.remove(job_opt_name)
+
+
+def test_lumi_fails_on_MC():
+    """
+    Check if enabling lumi counters fails on simulated input files.
+    """
+    options.simulation = True
+    options.lumi = True
+    with pytest.raises(DVRuntimeError):
+        check_options(options)
+    # Restore default value avoid failure in the next tests
+    options.lumi = False
+
+
+def test_merge_genfsr_fails_on_data():
+    """
+    Check that DaVinci raises a runtime error when trying to merge genFSRs on real data.
+    """
+    options.simulation = False
+    options.merge_genfsr = True
+    with pytest.raises(DVRuntimeError):
+        check_options(options)
+    # Restore default value avoid failure in the next tests
+    options.simulation = True
+    options.merge_genfsr = False
+
+
+def test_mcJob_fails_without_dddb():
+    """
+    Check that DaVinci job fails on simulated data if no dddb_tag condition is set.
+    """
+    options.dddb_tag = ""
+    with pytest.raises(DVOptionError):
+        check_options(options)
+
+
+def test_mcJob_fails_without_conddb():
+    """
+    Check that DaVinci job fails on simulated data if no conddb_tag condition is set. 
+    """
+    options.dddb_tag = "dddb-20171126"
+    options.conddb_tag = ""
+    with pytest.raises(DVOptionError):
+        check_options(options)
+    # Restore default value avoid failure in the next tests
+    options.dddb_tag = ""
+
+
+def test_set_data_option_without_override():
+    """
+    Check that DaVinci raises an error if the user tries to change the value of an input data option
+    without explicitely enabling the '--override' flag.
+    """
+    override_data_options = False
+    data_options = list_data_options(fileDB_key, fileDB_file)
+    with pytest.raises(DVRuntimeError):
+        is_option_settable(options, "data_type", data_options,
+                           override_data_options)
+
+
+def test_set_data_option_with_override():
+    """
+    Check that DaVinci updates the value of an input data option if the '--override' flag is enabled.
+    """
+    override_data_options = True
+    data_options = list_data_options(fileDB_key, fileDB_file)
+    assert is_option_settable(options, "data_type", data_options,
+                              override_data_options)
diff --git a/Phys/DaVinci/tests/config/test_configuration.py b/Phys/DaVinci/tests/config/test_configuration.py
new file mode 100644
index 0000000000000000000000000000000000000000..36caaea546b7106999ad02d3fa55727e93d4b564
--- /dev/null
+++ b/Phys/DaVinci/tests/config/test_configuration.py
@@ -0,0 +1,81 @@
+###############################################################################
+# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration           #
+#                                                                             #
+# This software is distributed under the terms of the GNU General Public      #
+# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
+#                                                                             #
+# In applying this licence, CERN does not waive the privileges and immunities #
+# granted to it by virtue of its status as an Intergovernmental Organization  #
+# or submit itself to any jurisdiction.                                       #
+###############################################################################
+
+import pytest
+
+from DaVinci.Configuration import run_davinci_app
+from DaVinci.config import prepare_davinci_nodes
+
+from pathlib import Path
+DIR = Path(__file__).parent.resolve()
+
+
+def test_run_app_dummy():
+    """
+    Check if DaVinci returns a ComponentConfig object even when passing only the input data.
+    """
+    from PyConf.application import ComponentConfig
+    configurables = run_davinci_app(
+        fileDB_key="Upgrade_Bd2KstarMuMu", fileDB_file="TestFileDB")
+    assert isinstance(configurables, ComponentConfig)
+
+
+def test_run_simple_job():
+    """
+    Check if DaVinci is able to set correctly the control flow application when running a simple job.
+    """
+    config = run_davinci_app(
+        fileDB_key="Upgrade_Bd2KstarMuMu",
+        fileDB_file="TestFileDB",
+        jobOpt_file=DIR / "../../options/jobOptions-Example.yaml",
+        simple_job=True)
+    assert "HLTControlFlowMgr/HLTControlFlowMgr" in config
+
+
+def test_set_hltAnnSvc():
+    """
+    Check if DaVinci is able to set correctly the HltAnnSvc given a specific .tck.json file.
+    """
+    config = run_davinci_app(
+        fileDB_key="Upgrade_Bd2KstarMuMu",
+        fileDB_file="TestFileDB",
+        ctx_args=[
+            "--annsvc_config",
+            "root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/spruce_all_lines_realtime.tck.json"
+        ])
+    assert "HltANNSvc/HltANNSvc" in config
+
+
+def test_lumi_counters_in_data():
+    """
+    Check that Lumi Counters are correctly added in the control flow when running on real data.
+    """
+    config = run_davinci_app(
+        fileDB_key="Upgrade_Bd2KstarMuMu",
+        fileDB_file="TestFileDB",
+        ctx_args=[
+            "--simulation", "False", "--write_fsr", "True", "--lumi", "True"
+        ],
+        override_data_options=True)
+    nodes = config["HLTControlFlowMgr/HLTControlFlowMgr"].CompositeCFNodes
+    # Node of the HLTControlFlowMgr are tuple containing : (<node_name>, <logic>, list_of_algs, <force_order>)
+    # E.g. : ('DaVinci', 'LAZY_AND', ['FileSummaryRecords', 'UserAnalysis'], True),
+    assert any("EventAccounting/EventAccount" in algs for algs in nodes[2])
+
+
+def test_prepare_davinci_nodes():
+    """
+    Check that DaVinci raises an error when trying to prepare a node with a set of algorithms different from a list.
+    """
+    from PyConf.Algorithms import Gaudi__Examples__VoidConsumer as VoidConsumer
+    list_of_algs = {"alg": VoidConsumer()}
+    with pytest.raises(ValueError):
+        prepare_davinci_nodes(list_of_algs)
diff --git a/Phys/DaVinci/tests/config/test_optionChecker.py b/Phys/DaVinci/tests/config/test_optionChecker.py
new file mode 100644
index 0000000000000000000000000000000000000000..2394bdba0680cb18e14c12c2e9b78185f21d30ae
--- /dev/null
+++ b/Phys/DaVinci/tests/config/test_optionChecker.py
@@ -0,0 +1,41 @@
+###############################################################################
+# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration           #
+#                                                                             #
+# This software is distributed under the terms of the GNU General Public      #
+# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
+#                                                                             #
+# In applying this licence, CERN does not waive the privileges and immunities #
+# granted to it by virtue of its status as an Intergovernmental Organization  #
+# or submit itself to any jurisdiction.                                       #
+###############################################################################
+import pytest
+from DaVinci.optionChecker import option_checker, DVOptionError, DVKeyError
+
+
+def test_get_allowed_values_for_known_option():
+    """
+    Check if DaVinci raises an error if the data_type is not allowed.
+    """
+    opt_name = "data_type"
+    opt_value = "2018"
+    with pytest.raises(DVOptionError):
+        option_checker(opt_name, opt_value)
+
+
+def test_get_allowed_values_for_unknown_option():
+    """
+    Check that DaVinci raise an error if checking allowed values on an unknown option.
+    """
+    opt_name = "data"
+    opt_value = "2018"
+    with pytest.raises(DVKeyError):
+        option_checker(opt_name, opt_value)
+
+
+def test_get_allowed_values_for_unrestricted_option():
+    """
+    Check that DaVinci does't raise an error if not allowed values are expected for a given option.
+    """
+    opt_name = "evt_max"
+    opt_value = "200"
+    option_checker(opt_name, opt_value)