diff --git a/.build.ci.sh b/.build.ci.sh
old mode 100644
new mode 100755
index 6e4c3265fe63ab5c6d4acf1c9d01e13c5e44658d..3710b9a60e58ff641bb95065c31ffc1b232cbc55
--- a/.build.ci.sh
+++ b/.build.ci.sh
@@ -1,31 +1,51 @@
 #!/bin/bash
 # This is wrapper to run the build.sh on CI
 
-echo "LCG_RELEASE: ${LCG_RELEASE}"
+echo "CEPCSW_LCG_RELEASE: ${CEPCSW_LCG_RELEASE}"
+echo "CEPCSW_LCG_PLATFORM: ${CEPCSW_LCG_PLATFORM}"
+echo "CEPCSW_LCG_VERSION: ${CEPCSW_LCG_VERSION}"
 echo "CEPCSW_BLDTOOL: ${CEPCSW_BLDTOOL}"
-buildpid=
-logfile=mylog.txt
 
-if [ "$LCG_RELEASE" = "KEY4HEP_STACK" ]; then
-    logfile=mylog-k4.sh
-    ./build-k4.sh >& ${logfile} &
-    buildpid=$!
-else
-    source setup.sh
-    ./build.sh >& ${logfile} &
-    buildpid=$!
-fi
+function build-with-log() {
+    buildpid=
+    logfile=mylog.txt
+
+    if [ "$CEPCSW_LCG_RELEASE" = "KEY4HEP_STACK" ]; then
+        logfile=mylog-k4.sh
+        ./build-k4.sh >& ${logfile} &
+        buildpid=$!
+    else
+        source setup.sh
+        ./build.sh >& ${logfile} &
+        buildpid=$!
+    fi
+
+    while ps -p $buildpid 2>/dev/null ; do
+        sleep 60
+    done &
+    echoer=$!
 
-while ps -p $buildpid 2>/dev/null ; do
-    sleep 60
-done &
-echoer=$!
+    trap 'kill $echoer' 0
 
-trap 'kill $echoer' 0
+    wait $buildpid
+    statuspid=$?
 
-wait $buildpid
-statuspid=$?
+    tail -n100 ${logfile}
 
-tail -n100 ${logfile}
+    exit $statuspid
+}
 
-exit $statuspid
+function build-with-stdout() {
+    if [ "$CEPCSW_LCG_RELEASE" = "KEY4HEP_STACK" ]; then
+        ./build-k4.sh
+    else
+        source setup.sh
+        ./build.sh
+    fi
+}
+
+if [ -n "${GITHUB_ACTION}" ]; then
+    build-with-log
+else
+    build-with-stdout
+fi
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index efd284358d4d0f3af8210fe838e90093a0103476..9064c2acfba738c7dd9b91c8884e04afdb15d769 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -26,19 +26,23 @@ workflow:
 
 stages:
   - build
-  # - test
 
 ##############################################################################
-# Build Template
+# Template for Build and Test
 ##############################################################################
+# Due to cmake/ctest will hardcode the path in build directory,
+# the test job will be failed if it is executed on a different nodes.
+# Therefore, put the build script and test script together.
+
 .build_template:
   stage: build
   variables:
-    LCG_RELEASE:
-    CEPCSW_BLDTOOL: ninja
+    CEPCSW_LCG_RELEASE:
+    CEPCSW_LCG_PLATFORM:
+    CEPCSW_LCG_VERSION:
   script:
     - bash ./.build.ci.sh
-
+    - bash ./.test.ci.sh
 
 ##############################################################################
 # Build CentOS 7 (LCG)
@@ -46,17 +50,13 @@ stages:
 build:lcg:el7:
   extends: .build_template
   variables:
-    LCG_RELEASE: LCG
+    CEPCSW_LCG_RELEASE: LCG
+    CEPCSW_LCG_PLATFORM: x86_64-centos7-gcc11-opt
+    CEPCSW_LCG_VERSION: 103.0.2
   tags:
     - centos7
-
-##############################################################################
-# Build CentOS 7 (KEY4HEP)
-##############################################################################
-# build:k4:el7:
-#   extends: .build_template
-#   variables:
-#     LCG_RELEASE: KEY4HEP_STACK
-#   tags:
-#     - centos7
-
+  artifacts:
+    paths:
+      - InstallArea
+    reports:
+      junit: build.${CEPCSW_LCG_VERSION}.${CEPCSW_LCG_PLATFORM}/cepcsw-ctest-result.xml
diff --git a/.test.ci.sh b/.test.ci.sh
new file mode 100755
index 0000000000000000000000000000000000000000..45f07bafae13e32e98555ae70c8320fe8f552c4f
--- /dev/null
+++ b/.test.ci.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Description:
+#   Run the tests using ctest
+#
+# Author:
+#   Tao Lin <lintao AT ihep.ac.cn>
+
+##############################################################################
+# Utilities
+##############################################################################
+function build-dir() {
+    local blddir=build
+
+    if [ -n "${CEPCSW_BLDTOOL}" ]; then
+        blddir=${blddir}.${CEPCSW_BLDTOOL}
+    fi
+
+    # If detect the extra env var, append it to the build dir
+    if [ -n "${CEPCSW_LCG_VERSION}" ]; then
+        blddir=${blddir}.${CEPCSW_LCG_VERSION}
+    fi
+    if [ -n "${CEPCSW_LCG_PLATFORM}" ]; then
+        blddir=${blddir}.${CEPCSW_LCG_PLATFORM}
+    fi
+
+    echo $blddir
+}
+
+function junit-output() {
+    local default=cepcsw-ctest-result.xml
+    echo ${CEPCSW_JUNIT_OUTPUT:-$default}
+}
+
+##############################################################################
+# Main
+##############################################################################
+
+
+echo "CEPCSW_LCG_RELEASE: ${CEPCSW_LCG_RELEASE}"
+echo "CEPCSW_LCG_PLATFORM: ${CEPCSW_LCG_PLATFORM}"
+echo "CEPCSW_LCG_VERSION: ${CEPCSW_LCG_VERSION}"
+echo "CEPCSW_BLDTOOL: ${CEPCSW_BLDTOOL}"
+
+source setup.sh
+
+ctest --output-junit $(junit-output) --test-dir $(build-dir)
diff --git a/Detector/DetCRD/CMakeLists.txt b/Detector/DetCRD/CMakeLists.txt
index 836cf2bf08f9f659e4dd1411836b09769f9566dc..f762843115db2b45e57697aa7239835938cc8cf8 100644
--- a/Detector/DetCRD/CMakeLists.txt
+++ b/Detector/DetCRD/CMakeLists.txt
@@ -42,3 +42,19 @@ install(TARGETS DetCRD
   RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
   LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib
   COMPONENT dev)
+
+################################################################################
+# Add tests
+################################################################################
+
+add_test(
+  NAME Test_TDR_o1_v01_Sim
+  COMMAND gaudirun.py Detector/DetCRD/scripts/TDR_o1_v01/sim.py
+  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+)
+
+add_test(
+  NAME Test_TDR_o1_v01_Rec
+  COMMAND gaudirun.py Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
+  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+)
diff --git a/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py b/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
index 5ce28166ee03116fd132c09890777fb2102ff695..2e76ba5520f7da020a6358e27be57336a12e7a60 100644
--- a/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
+++ b/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py
@@ -41,7 +41,8 @@ tracksystemsvc = TrackSystemSvc("TrackSystemSvc")
 
 from Configurables import SimplePIDSvc
 pidsvc = SimplePIDSvc("SimplePIDSvc")
-pidsvc.ParFile = "/cefs/higgs/zhaog/dndx_files/dNdx_TPC.root"
+cepcswdatatop = "/cvmfs/cepcsw.ihep.ac.cn/prototype/releases/data/latest"
+pidsvc.ParFile = os.path.join(cepcswdatatop, "CEPCSWData/offline-data/Service/SimplePIDSvc/data/dNdx_TPC.root")
 
 from Configurables import PodioInput
 podioinput = PodioInput("PodioReader", collections=[
diff --git a/build.sh b/build.sh
index 5c7393d169fd5b35240df699e7c1314b5cc783a3..85934189ecd1a6abd3fffec8ebe62aec3c00f45a 100755
--- a/build.sh
+++ b/build.sh
@@ -96,8 +96,8 @@ function run-install() {
 ##############################################################################
 
 # The current default platform
-lcg_platform=x86_64-centos7-gcc11-opt
-lcg_version=103.0.2
+lcg_platform=${CEPCSW_LCG_PLATFORM:-x86_64-centos7-gcc11-opt}
+lcg_version=${CEPCSW_LCG_VERSION:-103.0.2}
 
 bldtool=${CEPCSW_BLDTOOL} # make, ninja # set in env var