diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 651acd6fe1a58edc0b6f2c446e48e4bc4e4a8750..3efb308fa0f78dce35973ccb47d1303d7c8634af 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -10,9 +10,12 @@ stages:
   - build
   # Unit test stage
   - test
+  # Code coverage
+  - coverage
 
 include:
   - local: '/.gitlab/ci/_global.gitlab-ci.yml'
   - local: '/.gitlab/ci/static_analysis.gitlab-ci.yml'
   - local: '/.gitlab/ci/build.gitlab-ci.yml'
   - local: '/.gitlab/ci/test.gitlab-ci.yml'
+  - local: '/.gitlab/ci/coverage.gitlab-ci.yml'
diff --git a/.gitlab/ci/coverage.gitlab-ci.yml b/.gitlab/ci/coverage.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2b84acfa96eeafb94c928c632a238536da9e9385
--- /dev/null
+++ b/.gitlab/ci/coverage.gitlab-ci.yml
@@ -0,0 +1,39 @@
+coverage:ubuntu_cpp:
+  stage: coverage
+  needs: ["build:ubuntu_cpp"]
+  tags:
+    - docker
+  script:
+    - cd build_cpp
+    - ctest --output-on-failure
+    # HTML report for visualization
+    - gcovr --html-details --exclude-unreachable-branches -o coverage.html --root ${CI_PROJECT_DIR} --filter '\.\./include/' --filter '\.\./src/'
+    # Coberta XML report for Gitlab integration
+    - gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root ${CI_PROJECT_DIR} --filter '\.\./include/' --filter '\.\./src/'
+  coverage: /^\s*lines:\s*\d+.\d+\%/
+  artifacts:
+    name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
+    expire_in: 2 days
+    reports:
+      coverage_report:
+        coverage_format: cobertura
+        path: build_cpp/coverage.xml
+
+coverage:ubuntu_python:
+  stage: coverage
+  needs: ["build:ubuntu_python"]
+  tags:
+    - docker
+  script:
+    - source venv/bin/activate
+    - python3 -m pip install numpy coverage
+    - cd $PROJECT_NAME
+    - python3 -m coverage run --source=. -m unittest discover -s unit_tests/ -v -b
+    - python3 -m coverage report
+    - python3 -m coverage xml
+  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
+  artifacts:
+    reports:
+      coverage_report:
+        coverage_format: cobertura
+        path: $PROJECT_NAME/coverage.xml
diff --git a/.gitlab/ci/static_analysis.gitlab-ci.yml b/.gitlab/ci/static_analysis.gitlab-ci.yml
index 7490b5af51ca970c1b892408ac0023d8cd945cfa..4dd476133380399f4063ae755d8c6f5f72aa9adf 100644
--- a/.gitlab/ci/static_analysis.gitlab-ci.yml
+++ b/.gitlab/ci/static_analysis.gitlab-ci.yml
@@ -26,8 +26,8 @@ static_analysis:python:
   script:
     - pip install pylint
     - pip install pylint-gitlab
-    - pylint --rcfile=.pylintrc --exit-zero --output-format=pylint_gitlab.GitlabCodeClimateReporter aidge_backend_cpu/ > codeclimate.json
-    - pylint --rcfile=.pylintrc --exit-zero --output-format=pylint_gitlab.GitlabPagesHtmlReporter aidge_backend_cpu/ > pylint.html
+    - pylint --rcfile=.pylintrc --exit-zero --output-format=pylint_gitlab.GitlabCodeClimateReporter $PROJECT_NAME/ > codeclimate.json
+    - pylint --rcfile=.pylintrc --exit-zero --output-format=pylint_gitlab.GitlabPagesHtmlReporter $PROJECT_NAME/ > pylint.html
     - mkdir -p public/python/$CI_COMMIT_REF_NAME
     - mv pylint.html public/python/$CI_COMMIT_REF_NAME/
   artifacts:
diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml
index 2bad9b51cd61bcef9adf880ee1ed682499d229eb..709a60903d8944d9822228ac06f1e6c386ea71d0 100644
--- a/.gitlab/ci/test.gitlab-ci.yml
+++ b/.gitlab/ci/test.gitlab-ci.yml
@@ -17,7 +17,7 @@ test:ubuntu_python:
     - docker
   script:
     - source venv/bin/activate
-    - cd aidge_backend_cpu
+    - cd $PROJECT_NAME
     - python3 -m pip install numpy unittest-xml-reporting
     - python3 -m pip list
     # Run on discovery all tests located in core/unit_tests/python and discard the stdout 
@@ -25,7 +25,7 @@ test:ubuntu_python:
     - python3 -m xmlrunner discover -s unit_tests/ -v -b --output-file xmlrunner-results.xml
   artifacts:
     reports:
-      junit: aidge_core/xmlrunner-results.xml
+      junit: $PROJECT_NAME/xmlrunner-results.xml
 
 test:windows_cpp:
   stage: test
diff --git a/README.md b/README.md
index 0a0fe37f8672fde09055d3356951579bd1b56d6c..74eb50826bf6f88a0ded363138adba04827390d0 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+![Pipeline status](https://gitlab.eclipse.org/eclipse/aidge/aidge_backend_cpu/badges/master/pipeline.svg?ignore_skipped=true) ![C++ coverage](https://gitlab.eclipse.org/eclipse/aidge/aidge_backend_cpu/badges/master/coverage.svg?job=coverage:ubuntu_cpp&key_text=C%2B%2B+coverage&key_width=90) ![Python coverage](https://gitlab.eclipse.org/eclipse/aidge/aidge_backend_cpu/badges/master/coverage.svg?job=coverage:ubuntu_python&key_text=Python+coverage&key_width=100)
+
 # Aidge CPU library
 
 You can find in this folder the library that implements the CPU operators. <br>