diff --git a/.gitignore b/.gitignore
index 56f7580de26e47f75f8bf16346b35f35e229491d..e0f8501490a85015a57c7280aeba872fcb2c0692 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,6 +53,7 @@ coverage.xml
 .pytest_cache/
 .benchmarks/
 cover/
+*_report.xml
 
 # Translations
 *.mo
diff --git a/run_tests_docker.sh b/run_tests_docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fd885140999ac0f045c162f361f0075af96a8d48
--- /dev/null
+++ b/run_tests_docker.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+########################################################################################################################
+# Define your deployment settings here
+########################################################################################################################
+
+# Set the URL of your local Docker registry where the images will be uploaded to. Leave it blank if you do not want to
+# use any Docker registry.
+REGISTRY_IMAGE=""
+#REGISTRY_IMAGE="http://my-container-registry.local/"
+
+# Set the list of components you want to build images for, and deploy.
+COMPONENTS="context device automation policy service compute monitoring centralizedattackdetector"
+
+# Set the tag you want to use for your images.
+IMAGE_TAG="tf-dev"
+
+# Constants
+TMP_FOLDER="./tmp"
+
+TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
+mkdir -p $TMP_LOGS_FOLDER
+
+for COMPONENT in $COMPONENTS; do
+    echo "Processing '$COMPONENT' component..."
+    IMAGE_NAME="$COMPONENT:$IMAGE_TAG"
+    IMAGE_URL="$REGISTRY_IMAGE/$IMAGE_NAME"
+
+    echo "  Building Docker image..."
+    BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log"
+
+    if [ "$COMPONENT" == "automation" ] || [ "$COMPONENT" == "policy" ]; then
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
+    else 
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/ > "$BUILD_LOG"
+    fi
+
+    if [ -n "$REGISTRY_IMAGE" ]; then
+        echo "Pushing Docker image to '$REGISTRY_IMAGE'..."
+
+        TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log"
+        docker tag "$IMAGE_NAME" "$IMAGE_URL" > "$TAG_LOG"
+
+        PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log"
+        docker push "$IMAGE_URL" > "$PUSH_LOG"
+    fi
+done
+
+echo "Preparing for running the tests..."
+
+if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create -d bridge teraflowbridge; fi  
+
+for COMPONENT in $COMPONENTS; do
+    IMAGE_NAME="$COMPONENT:$IMAGE_TAG"
+    echo "  Running tests for $COMPONENT:"
+    docker run -it -d --name $COMPONENT $IMAGE_NAME --network=teraflowbridge
+    docker exec -it $COMPONENT bash -c "pytest --log-level=DEBUG --verbose $COMPONENT/tests/test_unitary.py"
+    docker stop $COMPONENT
+done
diff --git a/scripts/build_run_report_tests_locally.sh b/scripts/build_run_report_tests_locally.sh
new file mode 100755
index 0000000000000000000000000000000000000000..9bdc81d9894df35a6bcc325d78e7f1f5214e8a96
--- /dev/null
+++ b/scripts/build_run_report_tests_locally.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+die () {
+    echo >&2 "$@"
+    exit 1
+}
+
+[ "$#" -eq 1 ] || die "component name required but not provided"
+
+COMPONENT_NAME=$1 # parameter
+IMAGE_NAME="${COMPONENT_NAME}-local"
+IMAGE_TAG="latest"
+
+if docker ps | grep $IMAGE_NAME
+then
+    docker stop $IMAGE_NAME
+fi
+
+if docker network list | grep teraflowbridge
+then
+    echo "teraflowbridge is already created"
+else
+    docker network create -d bridge teraflowbridge
+fi
+
+docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$COMPONENT_NAME/Dockerfile .
+
+docker run --name $IMAGE_NAME -d -v "${PWD}/src/${COMPONENT_NAME}/tests:/home/${COMPONENT_NAME}/results" --network=teraflowbridge --rm $IMAGE_NAME:$IMAGE_TAG
+
+docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $COMPONENT_NAME/tests/ --junitxml=/home/${COMPONENT_NAME}/results/${COMPONENT_NAME}_report.xml"
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+echo
+echo "Coverage report:"
+echo "----------------"
+docker exec -i $IMAGE_NAME bash -c "coverage report --include='${COMPONENT_NAME}/*' --show-missing"
+
+# docker stop $IMAGE_NAME
+docker rm -f $IMAGE_NAME
+docker network rm teraflowbridge
diff --git a/tutorial/3-2-develop-cth.md b/tutorial/3-2-develop-cth.md
index eda70c9e8c411c8cc6a0ed0832f573ca787962ca..1b2a4690a3177628e18a4ca6f77365f515d6dcc5 100644
--- a/tutorial/3-2-develop-cth.md
+++ b/tutorial/3-2-develop-cth.md
@@ -1,5 +1,18 @@
 # 3.2. Development Commands, Tricks, and Hints (WORK IN PROGRESS)
 
+## Building, running, testing and reporting code coverage locally
+
+The project runs a CI/CD loops that ensures that all tests are run whenever new code is committed to our reporitory.
+However, committing and waiting for the pipeline to run can take substantial time.
+For this reason, we prepared a script that runs in your local machine, builds the container image and executes the tests within the image.
+
+To use the script receives one argument that is the name of the component you want to run.
+For instance, if you want to build and run the tests of the `compute` component, you can run:
+
+```shell
+scripts/build_run_report_tests_locally.sh compute
+```
+
 
 
 ## Items to be addressed: