diff --git a/CI/run_pytest_coverage.sh b/CI/run_pytest_coverage.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a22833446799a2132e0db934caf93dd8d1a5cdc7
--- /dev/null
+++ b/CI/run_pytest_coverage.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# run coverage twice, 1) for html deploy 2) for success evaluation
+coverage run --source='.' manage.py test
+coverage html
+coverage report | tee coverage_results.out
+
+IS_FAILED=$?
+
+# move html coverage report
+mkdir coverage/
+BRANCH_NAME=$( echo -e "${CI_COMMIT_REF_NAME////_}")
+mkdir coverage/${BRANCH_NAME}
+mkdir coverage/recent
+cp -r htmlcov/* coverage/${BRANCH_NAME}/.
+cp -r htmlcov/* coverage/recent/.
+if [[ "${CI_COMMIT_REF_NAME}" = "master" ]]; then
+    cp -r htmlcov/* coverage/.
+fi
+
+# extract coverage information
+COVERAGE_RATIO="$(grep -oP '\d+\%' coverage_results.out | tail -1)"
+COVERAGE_RATIO="$(echo ${COVERAGE_RATIO} | (grep -oP '\d*'))"
+
+# report
+if [[ ${IS_FAILED} == 0 ]]; then
+    if [[ ${COVERAGE_RATIO} -lt ${COVERAGE_PASS_THRESHOLD} ]]; then
+        echo "only ${COVERAGE_RATIO}% covered"
+        echo "incomplete" > status.txt
+        echo "${COVERAGE_RATIO}%25" > incomplete.txt
+        if [[ ${COVERAGE_RATIO} -lt ${FAILURE_THRESHOLD} ]]; then
+            echo -e "\033[1;31monly ${COVERAGE_RATIO}% covered!!\033[0m"
+            exit 1
+        fi
+    else
+        echo "passed"
+        echo "success" > status.txt
+        echo "${COVERAGE_RATIO}%25" > success.txt
+    fi
+    exit 0
+else
+    echo "not passed"
+    exit 1
+fi