Aller au contenu principal

TP8 - Tests d'API avec Postman

Lab Pratique 45 min Intermediaire

Objectifs

a la fin de ce lab, vous serez capable de :

  • Creer une collection Postman pour votre API de prediction IA
  • ecrire des scripts de test qui valident automatiquement les reponses
  • Utiliser des variables d'environnement pour basculer entre local et production
  • Executer la collection complete avec le Collection Runner
  • Exporter la collection pour le controle de version et le CI/CD avec Newman

Prerequis

  • Postman installe (telecharger ici)
  • Votre API de prediction FastAPI en cours d'execution localement (depuis TP3 ou TP7)
  • API accessible sur http://localhost:8000
Demarrer votre API d'abord

Avant de commencer ce lab, demarrez votre API dans un terminal :

uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

Verifiez qu'elle fonctionne : ouvrez http://localhost:8000/docs dans votre navigateur.


Vue d'ensemble de l'architecture


etape 1 — Creer l'environnement

1.1 Creer un environnement « Local »

  1. Dans Postman, cliquez sur Environments dans la barre laterale gauche
  2. Cliquez sur + pour creer un nouvel environnement
  3. Nommez-le AI API - Local
  4. Ajoutez les variables suivantes :
VariableTypeValeur initialeValeur actuelle
base_urldefaulthttp://localhost:8000http://localhost:8000
api_versiondefaultv1v1
expected_features_countdefault55
  1. Cliquez sur Save
  2. Selectionnez cet environnement dans le menu deroulant en haut a droite

1.2 (Optionnel) Creer un environnement « Staging »

VariableTypeValeur initiale
base_urldefaulthttps://staging-api.yourapp.com
api_versiondefaultv1
expected_features_countdefault5

etape 2 — Creer la collection

2.1 Initialiser la collection

  1. Cliquez sur Collections+Blank Collection
  2. Nommez-la AI Prediction API Tests
  3. Ajoutez une description :
Suite de tests complete pour l'API de prediction IA.
Teste les controles de sante, les predictions, la gestion des erreurs et les cas limites.

2.2 Creer la structure des dossiers

Clic droit sur la collection → Add Folder pour chacun :

  1. Health & Status
  2. Valid Predictions
  3. Error Handling
  4. Edge Cases

etape 3 — Ajouter les requetes et scripts de test

3.1 Controle de sante (GET)

  1. Clic droit sur Health & StatusAdd Request
  2. Nom : Health Check
  3. Methode : GET
  4. URL : {{base_url}}/health

Script post-reponse :

pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});

pm.test("Response time is under 500ms", function () {
pm.expect(pm.response.responseTime).to.be.below(500);
});

pm.test("Content-Type is JSON", function () {
pm.response.to.have.header("Content-Type", "application/json");
});

const data = pm.response.json();

pm.test("Status is healthy", function () {
pm.expect(data.status).to.equal("healthy");
});

pm.test("Model is loaded", function () {
pm.expect(data.model_loaded).to.be.true;
});

pm.test("Model version is present", function () {
pm.expect(data).to.have.property("model_version");
pm.expect(data.model_version).to.be.a("string");
});

// Save model version for other requests
pm.collectionVariables.set("model_version", data.model_version);
console.log("Model version:", data.model_version);

3.2 Prediction unique (POST)

  1. Ajoutez dans le dossier Valid Predictions
  2. Nom : Single Prediction
  3. Methode : POST
  4. URL : {{base_url}}/api/{{api_version}}/predict
  5. Body → raw → JSON :
{
"features": [5.1, 3.5, 1.4, 0.2, 2.3]
}

Script post-reponse :

pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});

pm.test("Response time is under 1000ms", function () {
pm.expect(pm.response.responseTime).to.be.below(1000);
});

const data = pm.response.json();

pm.test("Prediction is present", function () {
pm.expect(data).to.have.property("prediction");
});

pm.test("Prediction is an integer", function () {
pm.expect(Number.isInteger(data.prediction)).to.be.true;
});

pm.test("Prediction is class 0 or 1", function () {
pm.expect(data.prediction).to.be.oneOf([0, 1]);
});

pm.test("Confidence is present and valid", function () {
pm.expect(data).to.have.property("confidence");
pm.expect(data.confidence).to.be.a("number");
pm.expect(data.confidence).to.be.at.least(0);
pm.expect(data.confidence).to.be.at.most(1);
});

pm.test("Model version matches", function () {
pm.expect(data).to.have.property("model_version");
pm.expect(data.model_version).to.be.a("string");
});

// Save for chaining
pm.collectionVariables.set("last_prediction", data.prediction);
pm.collectionVariables.set("last_confidence", data.confidence);

3.3 Prediction avec features aleatoires (POST)

  1. Ajoutez dans le dossier Valid Predictions
  2. Nom : Random Features Prediction
  3. Methode : POST
  4. URL : {{base_url}}/api/{{api_version}}/predict

Script pre-requete :

const features = [];
for (let i = 0; i < 5; i++) {
features.push(parseFloat((Math.random() * 10 - 5).toFixed(3)));
}
pm.variables.set("random_features", JSON.stringify(features));
console.log("Generated random features:", features);

Body → raw → JSON :

{
"features": {{random_features}}
}

Script post-reponse :

pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});

const data = pm.response.json();

pm.test("Prediction is valid class", function () {
pm.expect(data.prediction).to.be.oneOf([0, 1]);
});

pm.test("Confidence is between 0 and 1", function () {
pm.expect(data.confidence).to.be.at.least(0);
pm.expect(data.confidence).to.be.at.most(1);
});

3.4 Erreur : features vides (POST)

  1. Ajoutez dans le dossier Error Handling
  2. Nom : Empty Features
  3. Methode : POST
  4. URL : {{base_url}}/api/{{api_version}}/predict
  5. Body :
{
"features": []
}

Script post-reponse :

pm.test("Status code is 422 (validation error)", function () {
pm.response.to.have.status(422);
});

pm.test("Error detail is present", function () {
const data = pm.response.json();
pm.expect(data).to.have.property("detail");
});

3.5 Erreur : body manquant (POST)

  1. Ajoutez dans le dossier Error Handling
  2. Nom : Missing Request Body
  3. Methode : POST
  4. URL : {{base_url}}/api/{{api_version}}/predict
  5. Body : aucun (laisser vide)

Script post-reponse :

pm.test("Status code is 422", function () {
pm.response.to.have.status(422);
});

3.6 Erreur : types de donnees incorrects (POST)

  1. Ajoutez dans le dossier Error Handling
  2. Nom : String Features
  3. Body :
{
"features": ["a", "b", "c", "d", "e"]
}

Script post-reponse :

pm.test("Status code is 422 for string features", function () {
pm.response.to.have.status(422);
});

pm.test("Error mentions type issue", function () {
const data = pm.response.json();
const detail = JSON.stringify(data.detail).toLowerCase();
pm.expect(detail).to.include("type");
});

3.7 Erreur : trop peu de features (POST)

  1. Ajoutez dans le dossier Error Handling
  2. Nom : Too Few Features
  3. Body :
{
"features": [1.0, 2.0]
}

Script post-reponse :

pm.test("Status code is 422 for insufficient features", function () {
pm.response.to.have.status(422);
});

3.8 Cas limite : toutes les valeurs a zero (POST)

  1. Ajoutez dans le dossier Edge Cases
  2. Nom : All Zero Features
  3. Body :
{
"features": [0.0, 0.0, 0.0, 0.0, 0.0]
}

Script post-reponse :

pm.test("Status code is 200 (zeros are valid)", function () {
pm.response.to.have.status(200);
});

const data = pm.response.json();

pm.test("Prediction is still valid", function () {
pm.expect(data.prediction).to.be.oneOf([0, 1]);
});

3.9 Cas limite : valeurs negatives (POST)

  1. Ajoutez dans le dossier Edge Cases
  2. Nom : Negative Features
  3. Body :
{
"features": [-10.0, -5.0, -2.5, -1.0, -0.5]
}

Script post-reponse :

pm.test("Status code is 200 (negatives are valid)", function () {
pm.response.to.have.status(200);
});

pm.test("Prediction is valid", function () {
const data = pm.response.json();
pm.expect(data.prediction).to.be.oneOf([0, 1]);
});

3.10 Cas limite : valeurs tres grandes (POST)

  1. Ajoutez dans le dossier Edge Cases
  2. Nom : Very Large Features
  3. Body :
{
"features": [999999.0, 999999.0, 999999.0, 999999.0, 999999.0]
}

Script post-reponse :

pm.test("API handles extreme values gracefully", function () {
pm.expect(pm.response.code).to.be.oneOf([200, 400]);
});

etape 4 — Executer la collection

4.1 Utiliser le Collection Runner

  1. Cliquez sur le bouton Run (▶️) de la collection
  2. Dans la configuration du Runner :
    • Environment : AI API - Local
    • Iterations : 1
    • Delay : 100 ms
  3. Cliquez sur Run AI Prediction API Tests

4.2 Analyser les resultats

Une fois l'execution terminee, vous verrez :

  • ✅ Vert = test reussi
  • ❌ Rouge = test echoue
  • Totaux des reussites/echecs
  • Temps de reponse pour chaque requete
Si les tests echouent
  1. Verifiez que votre API est en cours d'execution (http://localhost:8000/health)
  2. Verifiez que l'environnement est selectionne (menu deroulant en haut a droite)
  3. Consultez la Console (panneau du bas) pour les messages d'erreur detailles
  4. Assurez-vous que votre API correspond au format de reponse attendu

4.3 Executer plusieurs iterations

Relancez avec Iterations : 5 pour effectuer un test de charge sur votre API. La requete avec features aleatoires generera des entrees differentes a chaque fois.


etape 5 — Exporter la collection

5.1 Exporter la collection

  1. Clic droit sur la collection → Export
  2. Choisissez le format Collection v2.1
  3. Enregistrez sous postman/ai-prediction-api.postman_collection.json

5.2 Exporter l'environnement

  1. Allez dans Environments → cliquez sur les trois points sur AI API - Local
  2. Export
  3. Enregistrez sous postman/local.postman_environment.json

5.3 Ajouter au controle de version

project/
├── app/
├── tests/
├── postman/
│ ├── ai-prediction-api.postman_collection.json
│ └── local.postman_environment.json
└── ...

etape 6 — Automatiser avec Newman

6.1 Installer Newman

npm install -g newman

6.2 Executer en ligne de commande

newman run postman/ai-prediction-api.postman_collection.json \
-e postman/local.postman_environment.json

6.3 Executer avec rapport HTML

npm install -g newman-reporter-htmlextra

newman run postman/ai-prediction-api.postman_collection.json \
-e postman/local.postman_environment.json \
-r htmlextra \
--reporter-htmlextra-export reports/postman-report.html

6.4 Sortie Newman attendue

AI Prediction API Tests

❏ Health & Status
↳ Health Check
GET http://localhost:8000/health [200 OK, 256B, 23ms]
✓ Status code is 200
✓ Response time is under 500ms
✓ Content-Type is JSON
✓ Status is healthy
✓ Model is loaded
✓ Model version is present

❏ Valid Predictions
↳ Single Prediction
POST http://localhost:8000/api/v1/predict [200 OK, 178B, 89ms]
✓ Status code is 200
✓ Response time is under 1000ms
✓ Prediction is present
✓ Prediction is an integer
✓ Prediction is class 0 or 1
✓ Confidence is present and valid
✓ Model version matches

❏ Error Handling
↳ Empty Features
POST http://localhost:8000/api/v1/predict [422 Unprocessable Entity, 312B, 8ms]
✓ Status code is 422 (validation error)
✓ Error detail is present

...

┌─────────────────────────┬──────────┬──────────┐
│ │ executed │ failed │
├─────────────────────────┼──────────┼──────────┤
│ iterations │ 1 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ requests │ 10 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ test-scripts │ 20 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ assertions │ 28 │ 0 │
└─────────────────────────┴──────────┴──────────┘

Liste de validation

Avant de passer au lab suivant, verifiez :

  • Environnement « AI API - Local » cree avec base_url et api_version
  • Collection avec 4 dossiers : Health, Valid Predictions, Error Handling, Edge Cases
  • Au moins 10 requetes creees avec scripts de test
  • Collection Runner : tous les tests passent (✅ vert)
  • Collection exportee en JSON
  • Newman fonctionne en ligne de commande

Resume des tests crees

#RequeteMethodeStatut attenduTests
1Health CheckGET200Statut, modele charge, version
2Single PredictionPOST200Prediction, confiance, schema
3Random FeaturesPOST200Classe valide, plage de confiance
4Empty FeaturesPOST422Detail d'erreur present
5Missing BodyPOST422Erreur de validation
6String FeaturesPOST422Detail d'erreur de type
7Too Few FeaturesPOST422Erreur de validation
8All ZerosPOST200Prediction valide
9Negative ValuesPOST200Prediction valide
10Very Large ValuesPOST200/400Gestion gracieuse
Bravo !

Vous maitrisez maintenant Postman pour tester votre API. Combine avec pytest (TP7), vous disposez de deux approches complementaires : pytest pour l'automatisation CI/CD, Postman pour l'exploration et la documentation.