diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f094a6e60b5597a0eaef19bc0d622a17513e6cab..423a005e811b373fcbd122c3127502a8079c1afb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -23,7 +23,10 @@ test:
   before_script:
     - adduser --disabled-password --gecos "Test User" testuser
   script:
-    - sudo -u testuser tox -e py38
+    - sudo -u testuser tox -e py38 -- --junitxml=.tox/junit.xml
+  artifacts:
+    reports:
+      junit: .tox/junit.xml
 
 lint:
   stage: test
diff --git a/biscuit/core/tests/browser/test_selenium.py b/biscuit/core/tests/browser/test_selenium.py
index 0ff3d2cf9ea20be4b2f3a3466385393cd2d63284..4fff999cab330c75c6166b55307919f682970d4f 100644
--- a/biscuit/core/tests/browser/test_selenium.py
+++ b/biscuit/core/tests/browser/test_selenium.py
@@ -6,6 +6,8 @@ from django.urls import reverse
 
 import pytest
 
+pytestmark = pytest.mark.django_db
+
 SeleniumTestCaseBase.external_host = os.environ.get("TEST_HOST", "") or None
 SeleniumTestCaseBase.browsers = list(
     filter(bool, os.environ.get("TEST_SELENIUM_BROWSERS", "").split(","))
@@ -27,13 +29,11 @@ class SeleniumTests(SeleniumTestCase):
         else:
             return False
 
-    @pytest.mark.django_db
     def test_index(self):
         self.selenium.get(self.live_server_url + "/")
         assert "BiscuIT" in self.selenium.title
         self._screenshot("index.png")
 
-    @pytest.mark.django_db
     def test_login_default_superuser(self):
         username = "admin"
         password = "admin"
diff --git a/biscuit/core/tests/models/test_person.py b/biscuit/core/tests/models/test_person.py
index 740031df0c419221d0299c7b3079ac4c2d490d1c..62861ae1d82b7359080b653049038c9e142a7a27 100644
--- a/biscuit/core/tests/models/test_person.py
+++ b/biscuit/core/tests/models/test_person.py
@@ -2,8 +2,9 @@ import pytest
 
 from biscuit.core.models import Person
 
+pytestmark = pytest.mark.django_db
+
 
-@pytest.mark.django_db
 def test_full_name():
     _person = Person.objects.create(first_name="Jane", last_name="Doe")
 
diff --git a/biscuit/core/tests/views/test_account.py b/biscuit/core/tests/views/test_account.py
index 2e4e7fb3cf748e3857baea4b3ea1ca2cffd03db8..48cf07028fb2ae232a6b1018550a23e8edb04ff4 100644
--- a/biscuit/core/tests/views/test_account.py
+++ b/biscuit/core/tests/views/test_account.py
@@ -3,8 +3,9 @@ from django.urls import reverse
 
 import pytest
 
+pytestmark = pytest.mark.django_db
+
 
-@pytest.mark.django_db
 def test_index_not_logged_in(client):
     response = client.get("/")
 
@@ -12,7 +13,6 @@ def test_index_not_logged_in(client):
     assert reverse(settings.LOGIN_URL) in response.content.decode("utf-8")
 
 
-@pytest.mark.django_db
 def test_login(client, django_user_model):
     username = "foo"
     password = "bar"
@@ -26,7 +26,6 @@ def test_login(client, django_user_model):
     assert reverse(settings.LOGIN_URL) not in response.content.decode("utf-8")
 
 
-@pytest.mark.django_db
 def test_index_not_linked_to_person(client, django_user_model):
     username = "foo"
     password = "bar"
@@ -40,7 +39,6 @@ def test_index_not_linked_to_person(client, django_user_model):
     assert "You are not linked to a person" in response.content.decode("utf-8")
 
 
-@pytest.mark.django_db
 def test_logout(client, django_user_model):
     username = "foo"
     password = "bar"
diff --git a/poetry.lock b/poetry.lock
index 725eb03cab7ad56a03f4d502b06f5d132d6a00fd..cf8f8520051e978d2a55056700f818a161164938 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1108,6 +1108,21 @@ version = ">=0.12"
 [package.extras]
 testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
 
+[[package]]
+category = "dev"
+description = "Pytest plugin for measuring coverage."
+name = "pytest-cov"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+version = "2.8.1"
+
+[package.dependencies]
+coverage = ">=4.4"
+pytest = ">=3.6"
+
+[package.extras]
+testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "virtualenv"]
+
 [[package]]
 category = "dev"
 description = "A Django plugin for pytest."
@@ -1135,6 +1150,19 @@ version = "0.1.post0"
 dj-database-url = "*"
 "testing.postgresql" = "*"
 
+[[package]]
+category = "dev"
+description = "pytest-sugar is a plugin for pytest that changes the default look and feel of pytest (e.g. progressbar, show tests that fail instantly)."
+name = "pytest-sugar"
+optional = false
+python-versions = "*"
+version = "0.9.2"
+
+[package.dependencies]
+packaging = ">=14.1"
+pytest = ">=2.9"
+termcolor = ">=1.1.0"
+
 [[package]]
 category = "main"
 description = "Advanced Python dictionaries with dot notation access"
@@ -1468,6 +1496,14 @@ version = "1.31.0"
 pbr = ">=2.0.0,<2.1.0 || >2.1.0"
 six = ">=1.10.0"
 
+[[package]]
+category = "dev"
+description = "ANSII Color formatting for output in terminal."
+name = "termcolor"
+optional = false
+python-versions = "*"
+version = "1.1.0"
+
 [[package]]
 category = "dev"
 description = "A collection of helpers and mock objects for unit tests and doc tests."
@@ -1620,7 +1656,7 @@ testing = ["pathlib2", "contextlib2", "unittest2"]
 ldap = ["django-auth-ldap"]
 
 [metadata]
-content-hash = "be171a75e940a08dd4c63d1d7be5615b9cb23d844f6fe7b3e74a63d2871ae761"
+content-hash = "60137d4e1d5a9f537896b5a83a7ff282a776250334740728e423719a2040f2e2"
 python-versions = "^3.7"
 
 [metadata.files]
@@ -2159,6 +2195,10 @@ pytest = [
     {file = "pytest-5.3.1-py3-none-any.whl", hash = "sha256:63344a2e3bce2e4d522fd62b4fdebb647c019f1f9e4ca075debbd13219db4418"},
     {file = "pytest-5.3.1.tar.gz", hash = "sha256:f67403f33b2b1d25a6756184077394167fe5e2f9d8bdaab30707d19ccec35427"},
 ]
+pytest-cov = [
+    {file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"},
+    {file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"},
+]
 pytest-django = [
     {file = "pytest-django-3.7.0.tar.gz", hash = "sha256:17592f06d51c2ef4b7a0fb24aa32c8b6998506a03c8439606cb96db160106659"},
     {file = "pytest_django-3.7.0-py2.py3-none-any.whl", hash = "sha256:ef3d15b35ed7e46293475e6f282e71a53bcd8c6f87bdc5d5e7ad0f4d49352127"},
@@ -2167,6 +2207,10 @@ pytest-django-testing-postgresql = [
     {file = "pytest-django-testing-postgresql-0.1.post0.tar.gz", hash = "sha256:78b0c58930084cb4393407b2e5a2a3b8734c627b841ecef7d62d39bbfb8e8a45"},
     {file = "pytest_django_testing_postgresql-0.1.post0-py3-none-any.whl", hash = "sha256:78e52e3d1b0ef5f906d5d69247dd6ac7dfb10d840bd81abab92f3f8c30872cd3"},
 ]
+pytest-sugar = [
+    {file = "pytest-sugar-0.9.2.tar.gz", hash = "sha256:fcd87a74b2bce5386d244b49ad60549bfbc4602527797fac167da147983f58ab"},
+    {file = "pytest_sugar-0.9.2-py2.py3-none-any.whl", hash = "sha256:26cf8289fe10880cbbc130bd77398c4e6a8b936d8393b116a5c16121d95ab283"},
+]
 python-box = [
     {file = "python-box-3.4.6.tar.gz", hash = "sha256:694a7555e3ff9fbbce734bbaef3aad92b8e4ed0659d3ed04d56b6a0a0eff26a9"},
     {file = "python_box-3.4.6-py2.py3-none-any.whl", hash = "sha256:a71d3dc9dbaa34c8597d3517c89a8041bd62fa875f23c0f3dad55e1958e3ce10"},
@@ -2299,6 +2343,9 @@ stevedore = [
     {file = "stevedore-1.31.0-py2.py3-none-any.whl", hash = "sha256:01d9f4beecf0fbd070ddb18e5efb10567801ba7ef3ddab0074f54e3cd4e91730"},
     {file = "stevedore-1.31.0.tar.gz", hash = "sha256:e0739f9739a681c7a1fda76a102b65295e96a144ccdb552f2ae03c5f0abe8a14"},
 ]
+termcolor = [
+    {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"},
+]
 testfixtures = [
     {file = "testfixtures-6.10.3-py2.py3-none-any.whl", hash = "sha256:9334f64d4210b734d04abff516d6ddaab7328306a0c4c1268ce4624df51c4f6d"},
     {file = "testfixtures-6.10.3.tar.gz", hash = "sha256:8f22100d4fb841b958f64e71c8820a32dc46f57d4d7e077777b932acd87b7327"},
diff --git a/pyproject.toml b/pyproject.toml
index acbf2764d0be7938d0d5c078bbb19e429acc3afc..3e1299417d03784129bfda9d53ca58046619cf5d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -66,7 +66,6 @@ pytest-django = "^3.7"
 pytest-django-testing-postgresql = "^0.1"
 selenium = "^3.141.0"
 safety = "^1.8.5"
-coverage = "^4.5.4"
 flake8 = "^3.7.9"
 flake8-django = "^0.0.4"
 flake8-fixme = "^1.1.1"
@@ -79,6 +78,8 @@ black = "^19.10b0"
 flake8-black = "^0.1.1"
 isort = "^4.3.21"
 flake8-isort = "^2.8.0"
+pytest-cov = "^2.8.1"
+pytest-sugar = "^0.9.2"
 
 [tool.black]
 line-length = 100
diff --git a/tox.ini b/tox.ini
index 1ac69650b48a66cfd25d437012b66510c1fedfd2..528566fcb01fae119b1661a5f598ade8bc87f970 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,13 +12,14 @@ commands =
     poetry run python manage.py compilemessages
     poetry run python manage.py yarn install
     poetry run python manage.py collectstatic --no-input --clear
-    poetry run coverage run -a -m pytest {posargs} biscuit/core/
-    poetry run coverage report --include='*/biscuit/core/*'
-passenv =
-    TEST_SCREENSHOT_PATH
-    TEST_SELENIUM_HUB
-    TEST_SELENIUM_BROWSERS
-    TEST_HOST
+    poetry run pytest --cov=biscuit {posargs} biscuit/core/
+
+[testenv:selenium]
+setenv =
+    TEST_SCREENSHOT_PATH = {env:TEST_SCREENSHOT_PATH:.tox/screenshots}
+    TEST_SELENIUM_HUB = {env:TEST_SELENIUM_HUB:http://127.0.0.1:4444/wd/hub}
+    TEST_SELENIUM_BROWSERS = {env:TEST_SELENIUM_BROWSERS:chrome,firefox}
+    TEST_HOST = {env:TEST_HOST:172.17.0.1}
 
 [testenv:lint]
 commands =
@@ -70,6 +71,7 @@ django_settings_module = biscuit.core.settings
 
 [pytest]
 DJANGO_SETTINGS_MODULE = biscuit.core.settings
+junit_family = legacy
 
 [coverage:run]
 omit =