Comment tester une API web
Un test d’API envoie une requête et vérifie la réponse. Il ne regarde pas le code derrière l’API. Il pose seulement ce qu’un appelant poserait, et compare la réponse avec ce que l’API a promis.
Vous allez écrire quelques vérifications à la main, en voir une échouer, et tester ce qui arrive quand on envoie une requête deux fois.
À la fin de cette leçon
Remarque
Je peux tester une API avec de bonnes requêtes, de mauvaises requêtes et des reprises, et dire ce que prouve chaque vérification.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Cas de test | une requête et la réponse que l’on attend |
| Statut attendu | le code de statut que l’API doit renvoyer |
| Données de test | des lignes faites pour un test, que l’on peut retrouver et retirer |
| Reprise | renvoyer la même requête, parce que la première réponse s’est perdue |
| Idempotent | l’envoyer deux fois laisse les choses comme après l’avoir envoyée une fois |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une vérification : une requête et un statut
Taper curl et lire des nombres à l’œil ne passe pas à l’échelle. Écrivez la vérification une fois : un nom, le statut voulu et la requête.
Donnez d’abord le mot de passe à psql et créez la table livres. Puis définissez dans votre terminal une petite fonction nommée verifier, qui envoie la requête et dit REUSSI ou ECHEC.
Donner le mot de passe à psql
export PGPASSWORD=shopAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Créer la table livres
psql -h db -U shop -c "drop table if exists livres; create table livres (id serial primary key, titre text not null, annee int not null, disponible boolean not null default true); insert into livres (titre, annee, disponible) values ('Cartes de la mer', 1998, true), ('Fleuves du monde', 2004, false), ('Trains de nuit', 2011, true); notify pgrst, 'reload schema'"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Définir la fonction verifier
verifier() { attendu=$1; nom=$2; shift 2; obtenu=$(curl -s -o /dev/null -w '%{http_code}' "$@"); if [ "$obtenu" = "$attendu" ]; then echo "REUSSI $nom"; else echo "ECHEC $nom, attendu $attendu et obtenu $obtenu"; fi; }Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier une bonne requête
verifier 200 "lister les livres" "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier quelque chose qui doit échouer
verifier 200 "faux exprès" "http://api:3000/rien"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Tester ce que l’API refuse
La seconde vérification était fausse exprès, pour prouver que la fonction sait dire ECHEC. Une vérification qui affiche toujours REUSSI est pire que rien.
Une bonne série de tests passe autant de temps sur les mauvaises requêtes que sur les bonnes. Chacune doit revenir en 4xx avec le bon code, et ne doit pas changer les données.
Vérifier un livre sans titre
verifier 400 "sans titre" -X POST -H "Content-Type: application/json" -d '{"annee":2019}' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier un corps qui n’est pas du JSON
verifier 400 "json casse" -X POST -H "Content-Type: application/json" -d 'ceci n est pas du json' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier l’ajout d’un livre de test
verifier 201 "ajouter un livre" -X POST -H "Content-Type: application/json" -d '{"id":900,"titre":"Livre de test","annee":2020}' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier le même id de nouveau
verifier 409 "meme id encore" -X POST -H "Content-Type: application/json" -d '{"id":900,"titre":"Livre de test","annee":2020}' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier le corps en plus du statut
curl -s "http://api:3000/livres?id=eq.900" | grep -q '"titre":"Livre de test"' && echo "REUSSI le corps contient le titre" || echo "ECHEC le corps contient le titre"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Tester une requête envoyée deux fois
Les réseaux perdent des réponses, alors les clients renvoient la même requête. Une requête est idempotente si l’envoyer deux fois laisse les données comme après un seul envoi.
Testez-le en comptant les lignes. D’abord un changement qui fixe une valeur, puis un POST sans id, qui doit faire un nouveau livre à chaque fois.
Envoyer deux fois le même changement
for i in 1 2; do curl -s -o /dev/null -w "%{http_code}\n" -X PATCH -H "Content-Type: application/json" -d '{"disponible":false}' "http://api:3000/livres?id=eq.1"; doneAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Envoyer deux fois le même nouveau livre
for i in 1 2; do curl -s -o /dev/null -X POST -H "Content-Type: application/json" -d '{"titre":"Deux fois","annee":2020}' "http://api:3000/livres"; doneAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Compter les livres nommés Deux fois
psql -h db -U shop -At -c "select count(*) from livres where titre = 'Deux fois'"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Rendre une création rejouable
Deux livres nommés Deux fois veulent dire qu’une reprise a fait un doublon. Un appelant qui choisit l’id peut rendre la création sûre. Il envoie le même id, avec un en-tête qui dit « s’il est déjà là, mets-le à jour ».
Le premier appel répond 201 et le second 200. Les deux laissent une seule ligne.
Envoyer deux fois une création sûre
for i in 1 2; do curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" -H "Prefer: resolution=merge-duplicates" -d '{"id":902,"titre":"Une fois","annee":2020}' "http://api:3000/livres"; doneAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Compter les lignes avec cet id
psql -h db -U shop -At -c "select count(*) from livres where id = 902"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Exemple travaillé : quelles reprises sont sûres
| Requête envoyée deux fois | Lignes après la seconde | Reprise sûre ? |
|---|---|---|
| PATCH d’un livre vers disponible false | Les mêmes qu’après la première | Oui, elle fixe une valeur |
| POST d’un livre sans id | Une ligne de plus qu’après la première | Non, elle fait un doublon |
| POST avec un id et merge-duplicates | Les mêmes qu’après la première | Oui, l’id nomme la ligne |
| DELETE du livre 900 | Parti après la première, toujours parti | Oui, mais le labo répond 204 les deux fois |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Retirer les lignes de test
psql -h db -U shop -c "delete from livres where id >= 900 or titre = 'Deux fois'"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
Beaucoup ne testent que la bonne requête et ne voient jamais un échec. Testez ce qui est refusé. Nettoyez aussi vos lignes de test. Sinon la seconde exécution trouve les données laissées par la première, et échoue pour une raison étrangère à l’API.