Rust与Docker集成测试:高级进阶

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust与Docker集成测试:高级进阶



集成测试是Rust开发中至关重要的阶段,尤其是当您的应用需要与外部服务(如数据库、消息队列、HTTP-API)交互时。使用Docker可以创建隔离、可复现的测试环境。本文将介绍高级技巧:从基础配置到使用testcontainers和docker-compose实现并行测试执行。



为什么在集成测试中使用Docker?

传统的模拟对象和桩代码往往无法反映依赖的真实行为。Docker解决了这个问题:

  • 隔离性:每个测试在干净的容器中运行。
  • 可复现性:在所有开发人员机器和CI环境中保持一致的运行环境。
  • 并行性:可以同时运行多个测试数据库。


1. 基础配置:使用PostgreSQL进行测试

从简单开始:测试一个与PostgreSQL交互的函数。使用testcontainers crate——一个用于管理Docker容器的Rust封装。

在Cargo.toml中添加依赖:

[dev-dependencies]testcontainers = "0.18"tokio = { version = "1", features = ["full"] }sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"] }


测试示例:

use sqlx::PgPool;use testcontainers::clients::Cli;use testcontainers::images::postgres::Postgres;

#[tokio::test]async fn test_database_connection() { let docker = Cli::default(); let postgres_instance = docker.run(Postgres::default()); let connection_string = &format!( "postgres://postgres:postgres@127.0.0.1:{}/postgres", postgres_instance.get_host_port_ipv4(5432) );

let pool = PgPool::connect(connection_string).await.unwrap();

// 执行SQL查询 let row: (i32,) = sqlx::query_as("SELECT 1 + 1") .fetch_one(&pool) .await .unwrap(); assert_eq!(row.0, 2);}

重要提示:测试完成后容器会自动删除(得益于Drop实现)。



2. 高级配置:带迁移的自定义镜像

通常需要预先执行数据库迁移。基于Dockerfile创建自定义镜像:

# Dockerfile.testFROM postgres:16-alpineCOPY migrations/ /docker-entrypoint-initdb.d/


在Rust测试中使用Image:

use testcontainers::images::generic::GenericImage;

#[tokio::test]async fn test_with_migrations() { let docker = Cli::default(); let image = GenericImage::new("my-app-test:latest") .with_wait_for(testcontainers::core::WaitFor::message_on_stdout( "database system is ready to accept connections" )); let instance = docker.run(image); // ... 使用instance}

在CI中构建镜像可以使用docker build -f Dockerfile.test -t my-app-test:latest .



3. 使用Docker Compose并行执行测试

如果您的服务需要多个依赖(PostgreSQL + Redis),请使用docker-compose。创建docker-compose.test.yml文件:

version: '3.8'services:  postgres:    image: postgres:16-alpine    environment:      POSTGRES_PASSWORD: testpass    ports:      - "5432"  redis:    image: redis:7-alpine    ports:      - "6379"


在Rust测试中启动Compose环境:

use testcontainers::clients::Cli;use testcontainers::images::compose::Compose;

#[tokio::test]async fn test_with_compose() { let docker = Cli::default(); let compose = Compose::new("docker-compose.test.y

博客

书籍推荐