Skip to content

Module 2 — L'intégration continue (CI) en détail

Bonne lecture et bon apprentissage ! Junior TSAFACK – 12/09/2026 Temps de lecture estimé : 9 minutes


Le Module 1 a défini la Continuous Integration : construire et tester automatiquement chaque changement. Regardons concrètement ce que ça signifie, avec du code réellement exécuté.

Checkout repo → Build → ┬─ Analyse statique (lint) ─┐
├─ Tests unitaires ─────────┼─→ Package
└─ Tests d'intégration ─────┘
  • Checkout repo : récupérer le code source exact du commit à vérifier.
  • Build : compiler ou préparer le projet (pour un langage interprété comme Python, cette étape se réduit souvent à installer les dépendances).
  • Analyse statique (lint) : vérifier le style et détecter des erreurs évidentes sans exécuter le code (imports inutilisés, variables non définies, incohérences de style).
  • Tests unitaires / d’intégration : exécuter le code et vérifier que son comportement correspond à ce qui est attendu.

Ces vérifications peuvent s’exécuter en parallèle (rien n’empêche de lancer le lint et les tests en même temps, puisqu’ils sont indépendants) — c’est exactement ce que montrait le diagramme du Module 1.

Démonstration : un projet avec deux problèmes réels

Section titled “Démonstration : un projet avec deux problèmes réels”

Prenons un mini-projet Python volontairement imparfait :

calc.py (version initiale)
import os
def add(a, b):
return a + b
def divide(a, b):
return a / b
test_calc.py
from calc import add, divide
def test_add():
assert add(2, 3) == 5
def test_divide():
assert divide(10, 2) == 5
assert divide(7, 0) == 0
Terminal window
flake8 --max-line-length=100 calc.py test_calc.py

Sortie réellement obtenue :

calc.py:1:1: F401 'os' imported but unused

Un import inutile (os, jamais utilisé dans le fichier) — une erreur bénigne, mais exactement le genre de détail qu’un lint attrape systématiquement, sans qu’un humain ait besoin d’y penser à chaque relecture.

Terminal window
python -m pytest -v

Sortie réellement obtenue :

test_calc.py::test_add PASSED [ 50%]
test_calc.py::test_divide FAILED [100%]
================================== FAILURES ===================================
_________________________________ test_divide _________________________________
def test_divide():
assert divide(10, 2) == 5
> assert divide(7, 0) == 0
a = 7, b = 0
def divide(a, b):
> return a / b
E ZeroDivisionError: division by zero
calc.py:9: ZeroDivisionError
=========================== short test summary info ===========================
FAILED test_calc.py::test_divide - ZeroDivisionError: division by zero

Un vrai bug : la fonction divide ne gère pas la division par zéro, et le test qui l’exerce le révèle immédiatement — exactement le rôle d’une CI : ce commit n’ira pas plus loin dans le pipeline tant que ce problème n’est pas corrigé.

calc.py (corrigé)
def add(a, b):
return a + b
def divide(a, b):
if b == 0:
raise ValueError("division par zero non autorisee")
return a / b
test_calc.py (corrigé)
import pytest
from calc import add, divide
def test_add():
assert add(2, 3) == 5
def test_divide():
assert divide(10, 2) == 5
def test_divide_by_zero_raises():
with pytest.raises(ValueError):
divide(7, 0)
Terminal window
flake8 --max-line-length=100 calc.py test_calc.py && echo "OK (aucune sortie = aucune erreur)"
python -m pytest -v

Sortie réellement obtenue :

OK (aucune sortie = aucune erreur)
test_calc.py::test_add PASSED [ 33%]
test_calc.py::test_divide PASSED [ 66%]
test_calc.py::test_divide_by_zero_raises PASSED [100%]
============================== 3 passed in 0.02s ==============================

Une fois le code validé, la CI produit souvent un artefact : un package installable, une image de conteneur, un binaire — la forme exacte du logiciel qui sera réellement déployée.

Terminal window
python -m build

Sortie réellement obtenue (extrait) :

Successfully built demo_calc-0.1.0.tar.gz and demo_calc-0.1.0-py3-none-any.whl
Terminal window
ls dist/
demo_calc-0.1.0-py3-none-any.whl
demo_calc-0.1.0.tar.gz

Cet artefact — pas le code source brut — est ce que la suite du pipeline (la CD, voir Module 3) va déployer. C’est un principe important : on construit une fois, on déploie le même artefact partout (staging, puis production) plutôt que de reconstruire à chaque environnement, ce qui garantirait que l’environnement de test et l’environnement de production exécutent exactement le même code.

  • Une CI enchaîne (ou parallélise) : récupération du code, build, analyse statique, tests, puis production d’un artefact.
  • Un lint et des tests qui échouent sont le comportement attendu d’une CI qui fonctionne — ce n’est pas un problème du pipeline, c’est le pipeline qui fait exactement son travail.
  • L’artefact produit en fin de CI est ce qui sera déployé tel quel, sans reconstruction, à chaque étape suivante.

Module 3 : La livraison et le déploiement continus (CD)