Tests d'intégration Rust avec Docker : guide complet

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Tests d'intégration Rust avec Docker : de la théorie à la pratique



Le développement moderne en Rust nécessite non seulement la vérification de fonctions individuelles (tests unitaires), mais aussi le test des interactions des composants avec les services externes — bases de données, caches, API. Les tests d'intégration avec Docker permettent d'isoler l'environnement, de garantir la reproductibilité et d'éviter les problèmes de "ça marche sur ma machine". Dans cet article, nous allons voir comment configurer des tests d'intégration pour des applications Rust en utilisant Docker.



Pourquoi Docker pour les tests d'intégration Rust ?

Docker résout trois problèmes clés :

  • Isolation de l'environnement — les tests s'exécutent dans un conteneur propre, sans influence des paramètres locaux
  • Reproductibilité — des conditions identiques sur toutes les machines des développeurs et dans le CI/CD
  • Gestion des dépendances — démarrage automatique de PostgreSQL, Redis, Kafka et autres services


Configuration du projet : structure et dépendances

Créons un projet avec des tests d'intégration pour un serveur web basé sur Actix-web, qui fonctionne avec PostgreSQL.



# Cargo.toml[package]name = "rust-docker-testing"version = "0.1.0"edition = "2021"

[dependencies]actix-web = "4"serde = { version = "1", features = ["derive"] }tokio = { version = "1", features = ["full"] }sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }dotenv = "0.15"

[dev-dependencies]testcontainers = "0.14"reqwest = { version = "0.11", features = ["json"] }


Notez testcontainers — c'est une bibliothèque Rust pour gérer les conteneurs Docker directement depuis les tests.



Structure du projet

Structure recommandée pour les tests d'intégration :

.├── src/│   ├── main.rs│   ├── lib.rs│   ├── models.rs│   └── handlers.rs├── tests/│   ├── common/│   │   └── mod.rs          # Utilitaires communs pour les tests│   ├── integration_tests.rs # Tests d'intégration principaux│   └── docker-compose.yml  # Pour le lancement manuel├── Dockerfile└── .env


Étape 1 : Écrire un test d'intégration avec Docker

Créons un test qui démarre PostgreSQL dans Docker, exécute les migrations et vérifie l'API.



// tests/integration_tests.rsuse testcontainers::clients;use testcontainers::images::postgres::Postgres;use sqlx::postgres::PgPoolOptions;use std::net::TcpListener;

async fn setup_test_db() -> (String, testcontainers::Container) { let docker = clients::Cli::default(); let postgres_image = Postgres::default(); let container = docker.run(postgres_image); let host = container.get_host().unwrap(); let port = container.get_host_port_ipv4(5432).unwrap(); let database_url = format!("postgres://postgres:postgres@{}:{}/postgres", host, port); // Exécution des migrations let pool = PgPoolOptions::new() .max_connections(5) .connect(&database_url) .await .expect("Échec de connexion à Postgres"); sqlx::query("CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL)") .execute(&pool) .await .expect("Échec de la migration"); (database_url, container)}

#[tokio::test]async fn test_create_user() { let (db_url, _container) = setup_test_db().await; // Démarrage de l'application sur un port aléatoire let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); let server = actix_web::HttpServer::new(move || { actix_web::App::new() .app_data(actix_web::web::Data::new(db_url.clone())) .route("/users", actix_web::web::post().to(handlers::create_user)) }) .listen(listener) .unwrap() .run(); tokio::spawn(server); // Attente du démarrage du serveur tokio::ti

Blogs

Book Recommendations