0Pricing
Learn Rust Coding · Leçon

Tester l’API

Tests d’intégration

Tester l’API est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 4 leçons au total.

Pourquoi tester une API ?

Les tests vous donnent l’assurance que les points d’accès se comportent correctement et continuent de fonctionner lorsque vous modifiez le code. Pour une API REST, les tests les plus utiles sont les tests d’intégration : ils exercent le routeur réel de bout en bout, en envoyant des requêtes et en vérifiant les réponses.

Cette leçon couvre les tests unitaires, l’astuce oneshot de Tower et les tests d’intégration complets.

Tests unitaires pour la logique pure

La logique qui ne touche pas au réseau, comme la validation, peut être testée avec de simples tests unitaires Rust. Placez-les dans un module #[cfg(test)] à côté du code. Ils s’exécutent rapidement avec cargo test.

fn validate_title(title: &str) -> bool {
    !title.trim().is_empty()
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn rejects_empty() {
        assert!(!validate_title("   "));
        assert!(validate_title("buy milk"));
    }
}

Tests asynchrones

Les gestionnaires sont asynchrones ; les fonctions de test qui attendent un résultat doivent donc s’exécuter dans un environnement d’exécution. Utilisez #[tokio::test] plutôt que #[test]. Cela démarre un environnement Tokio pour ce test et vous permet d’appeler du code asynchrone avec .await.

async fn add(a: i32, b: i32) -> i32 { a + b }

#[cfg(test)]
mod tests {
    use super::*;
    #[tokio::test]
    async fn adds() {
        assert_eq!(add(2, 3).await, 5);
    }
}

Tester sans réseau

Les routeurs Axum implémentent le trait Service de Tower ; vous pouvez donc leur transmettre directement des requêtes sans lier de port. La méthode oneshot prend une seule Request et renvoie la Response. Les tests d’intégration deviennent ainsi rapides et déterministes.

// dev-dependencies needed: tower (for ServiceExt), http-body-util
use axum::{Router, routing::get};
use axum::http::{Request, StatusCode};
use axum::body::Body;
use tower::ServiceExt; // brings in oneshot

async fn check() {
    let app = Router::new().route("/health", get(|| async { "ok" }));
    let res = app
        .oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
        .await.unwrap();
    assert_eq!(res.status(), StatusCode::OK);
}

Vérifier le code de statut

La première chose que vérifient la plupart des tests est le statut HTTP. Une ressource absente doit renvoyer 404, une création réussie 201 et un corps incorrect 400. Construisez une requête pour la route et comparez res.status() au code attendu.

use axum::http::{Request, StatusCode};
use axum::body::Body;
use tower::ServiceExt;

async fn missing_returns_404(app: axum::Router) {
    let res = app
        .oneshot(Request::builder()
            .uri("/todos/999")
            .body(Body::empty()).unwrap())
        .await.unwrap();
    assert_eq!(res.status(), StatusCode::NOT_FOUND);
}

Lire le corps de la réponse

Pour vérifier du JSON, rassemblez le corps de la réponse sous forme d’octets et désérialisez-le. L’outil http_body_util::BodyExt::collect rassemble le corps, puis serde_json l’analyse dans votre modèle afin de permettre des vérifications champ par champ.

use http_body_util::BodyExt;

async fn read_json(res: axum::http::Response<axum::body::Body>) {
    let bytes = res.into_body().collect().await.unwrap().to_bytes();
    let todo: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
    assert_eq!(todo["done"], false);
}

Envoyer un corps JSON

Pour tester un POST, construisez une requête avec un corps JSON et l’en-tête de type de contenu approprié. Sérialisez votre structure d’entrée, définissez content-type: application/json et transmettez-la avec oneshot.

use axum::http::{Request, StatusCode, header};
use axum::body::Body;
use tower::ServiceExt;

async fn create_returns_201(app: axum::Router) {
    let body = serde_json::json!({ "title": "test" }).to_string();
    let res = app
        .oneshot(Request::builder()
            .method("POST").uri("/todos")
            .header(header::CONTENT_TYPE, "application/json")
            .body(Body::from(body)).unwrap())
        .await.unwrap();
    assert_eq!(res.status(), StatusCode::CREATED);
}

Un générateur d’application de test réutilisable

Chaque test doit partir d’un état vierge. Écrivez un utilitaire qui construit un routeur neuf avec une nouvelle base de données en mémoire ou de test. En l’appelant dans chaque test, vous les isolez afin qu’un test ne puisse pas en affecter un autre.

use axum::Router;
use std::sync::{Arc, Mutex};

fn test_app() -> Router {
    let store = Arc::new(Mutex::new(Vec::new()));
    build(store) // same build() the real server uses
}

Le répertoire des tests

Les tests d’intégration se trouvent dans un dossier tests/ situé à la racine. Chaque fichier qui s’y trouve est compilé comme une caisse distincte utilisant l’API publique de votre bibliothèque. Cela vous oblige à tester via la même interface que voient les utilisateurs réels.

  • tests/api.rs contient vos tests de points d’accès.
  • Exécutez-les tous avec cargo test.
// tests/api.rs
use my_api::build_router; // exported from lib.rs

#[tokio::test]
async fn health_ok() {
    let _app = build_router();
    // send a request and assert ...
}

Tester avec une base de données

Lorsque les gestionnaires utilisent sqlx, les tests ont également besoin d’une base de données. Stratégies courantes : une base de données de test dédiée, des transactions annulées après chaque test, ou la macro #[sqlx::test] de sqlx, qui crée automatiquement une base vierge pour chaque test.

// requires sqlx test features and a DATABASE_URL
use sqlx::PgPool;

#[sqlx::test]
async fn inserts_todo(pool: PgPool) {
    let todo = create(&pool, "learn rust").await.unwrap();
    assert_eq!(todo.title, "learn rust");
    assert_eq!(todo.done, false);
}

Que tester

Visez une suite équilibrée :

  • Parcours nominal : les requêtes valides renvoient le bon statut et le bon corps.
  • Erreurs : les ressources absentes renvoient 404 et les entrées incorrectes renvoient 400.
  • Cas limites : listes vides, valeurs aux limites et doublons.

Exécutez cargo test dans l’intégration continue afin de détecter les régressions avant le déploiement.

Vérification rapide

Vérifiez votre compréhension des tests d’API.

Récapitulatif

Vous avez appris à tester une API REST en Rust :

  • Testez la logique pure avec des tests unitaires ; utilisez #[tokio::test] pour le code asynchrone.
  • oneshot fait fonctionner directement le routeur, sans nécessiter de port.
  • Construisez des requêtes avec des corps et des en-têtes ; rassemblez et analysez les corps des réponses.
  • Utilisez un générateur d’application vierge pour chaque test afin de garantir l’isolation ; placez les tests d’intégration dans tests/.
  • #[sqlx::test] crée des bases de données vierges ; couvrez les parcours nominaux, les erreurs et les cas limites.

Questions Fréquemment Posées

La leçon « Tester l’API » est-elle gratuite ?

Oui — le texte complet de « Tester l’API » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Tester l’API » ?

Tests d’intégration Tu pratiques Learn Rust Coding avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Learn Rust Coding ?

Aucune expérience préalable n'est requise. Learn Rust Coding sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Tester l’API » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Learn Rust Coding ?

Oui. Chaque leçon Learn Rust Coding inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Configuration du projet
  2. Points d’accès et modèles
  3. Intégration de la base de données
  4. Tester l’API
← Retour à Learn Rust Coding