Aller au contenu

Python : qualité et tests

monprojet/
├── pyproject.toml
├── src/
│ └── monapp/
│ ├── __init__.py
│ └── calcul.py
└── tests/
└── test_calcul.py

Installer les outils dans l’environnement du projet :

Fenêtre de terminal
pip install pytest ruff mypy

src/monapp/calcul.py :

def additionner(a: int, b: int) -> int:
return a + b

tests/test_calcul.py :

import pytest
from monapp.calcul import additionner
def test_additionner():
assert additionner(2, 3) == 5
@pytest.mark.parametrize("a, b, attendu", [(0, 0, 0), (-1, 1, 0), (10, 5, 15)])
def test_cas(a, b, attendu):
assert additionner(a, b) == attendu
def test_exception():
with pytest.raises(TypeError):
additionner("a", None) + 1
Fenêtre de terminal
pytest # tous les tests
pytest -v # détail
pytest -x # s'arrête au premier échec
pytest tests/test_calcul.py::test_cas
pytest -k "cas" # tests dont le nom contient « cas »
pytest --lf # relance les derniers échecs

Configuration dans pyproject.toml :

[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]
import pytest
@pytest.fixture
def client():
return {"nom": "Alice", "email": "alice@exemple.com"}
def test_email(client):
assert client["email"].endswith("@exemple.com")
def test_fichier(tmp_path):
f = tmp_path / "donnees.txt"
f.write_text("ok")
assert f.read_text() == "ok"

tmp_path fournit un dossier temporaire propre à chaque test.

Fenêtre de terminal
ruff check . # analyse (erreurs probables, imports inutilisés…)
ruff check . --fix # corrige automatiquement ce qui peut l'être
ruff format . # formate le code
ruff format --check . # vérifie seulement (CI)

Configuration :

[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP"]
Jeu de règles Contrôle
E, F Style et erreurs (pyflakes)
I Tri des imports
B Pièges fréquents (bugbear)
UP Modernisation de la syntaxe
Fenêtre de terminal
mypy src
[tool.mypy]
python_version = "3.12"
strict = true

strict = true est exigeant : l’activer dès le début d’un projet, ou progressivement sur un projet existant.

Script verifier.sh :

#!/bin/bash
set -euo pipefail
ruff check .
ruff format --check .
mypy src
pytest -q
Fenêtre de terminal
chmod +x verifier.sh
./verifier.sh

La même suite s’exécute en intégration continue (voir Gitea : Actions).

Fenêtre de terminal
pip install pytest-cov
pytest --cov=monapp --cov-report=term-missing
Symptôme Piste
ModuleNotFoundError: No module named 'monapp' Ajouter pythonpath = ["src"] ou installer le projet : pip install -e .
Aucun test collecté Fichiers test_*.py, fonctions test_*
ruff: command not found Environnement non actif ou outil non installé
mypy signale des paquets sans types pip install types-requests (paquet types-… correspondant) ou ignore_missing_imports
Tests qui passent en local mais échouent en CI Versions non figées ou dépendance à l’ordre des tests

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Ces outils fonctionnent sous Python 3.12 et 3.14. Adapter target-version et python_version à la plus ancienne version que le projet doit supporter.