diff --git a/.gitignore b/.gitignore
index 142d9beaee82224a8925bb43fa8aeb7e20dce0e4..4baa4ea012c968b1009bd230cfabe0eae04dd543 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 *.egg-info/
 __pycache__
 .tox
+.coverage
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d0d3528d21a966f22b659e21291441fc56e793f7..bbfc4ff64070f03bf0368b0b0f58da4ad8e8b8ea 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -10,7 +10,7 @@ cache:
 
 linter:
   stage: test
-  image: python:3
+  image: python:3.10
 
   cache:
     paths:
@@ -31,7 +31,7 @@ linter:
 
 tests:
   stage: test
-  image: python:3
+  image: python:3.10
 
   cache:
     paths:
@@ -43,6 +43,9 @@ tests:
   script:
     - tox
 
+  # Process coverage report so that it shows up in Gitlab interface
+  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
+
 bump-python-deps:
   stage: release
   image: registry.gitlab.teklia.com/infra/devops:latest
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tox.ini b/tox.ini
index a8d512b63eed45b7718d4f48b55d9615769970e7..0594b2d2a9668089414d04862e00941a7f289094 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,11 +1,18 @@
 [tox]
 envlist = nerval
 
+[tool:pytest]
+testpaths = tests
+addopts =
+    --cov-report=term-missing
+
+
 [testenv]
 commands =
-  pytest {posargs}
+  pytest --cov=nerval {posargs}
 
 deps =
   pytest
   pytest-lazy-fixture
+  pytest-cov
   -rrequirements.txt