はじめに
Rust プロジェクトで VSCode の Rust Analyzer 拡張機能を使用すると、エディタ上で「▶ Run Test」から直接テストを実行できて便利です。
しかし、Docker 環境でデータベースに接続するようなプロジェクトの場合、環境の違いによりテストが失敗してしまうことがあります。
この記事では、Docker 環境でも快適にインラインテストを実行できる設定方法を紹介します。
環境
- VSCode
- Rust Analyzer 拡張機能
- Docker / Docker Compose
- データベースを使用する Rust プロジェクト
プロジェクト構成
以下のような構成のプロジェクトを想定します:
my-rust-project/
├── .vscode/
│ └── settings.json
├── src/
│ └── lib.rs
├── docker/
│ └── postgres/
│ └── init.sql
├── scripts/
│ └── run_cargo.sh
├── docker-compose.yml
├── Cargo.toml
└── .env
セットアップ手順
1. docker-compose.yml の作成
プロジェクトのルートディレクトリに以下の内容でdocker-compose.yml
を作成します:
name: myapp # プロジェクト名を指定(これがコンテナ名のプレフィックスになります)
services:
app:
build:
context: .
working_dir: /app
volumes:
- .:/app
- cargo-cache:/usr/local/cargo/registry
- target-cache:/app/target
environment:
- DATABASE_URL=postgres://postgres:password@db:5432/testdb
depends_on:
- db
tty: true
db:
image: postgres:17.2
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_DB=testdb
volumes:
- ./docker/postgres:/docker-entrypoint-initdb.d
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
cargo-cache:
target-cache:
postgres-data:
2. スクリプトの作成
scripts/run_cargo.sh
を以下の内容で作成します:
#!/bin/sh
set -e
COMPOSE_PROJECT_NAME="myapp" # docker-compose.yml の name と同じ値を設定
APP_SERVICE_NAME="app" # docker-compose.yml の services で定義したアプリケーションのサービス名
run_cargo() {
if docker compose ps --format json | grep -q "\"Name\":\"${COMPOSE_PROJECT_NAME}-${APP_SERVICE_NAME}\".*\"State\":\"running\""; then
echo "Running cargo in Docker container..."
docker compose exec ${APP_SERVICE_NAME} cargo "$@"
else
echo "Running cargo locally..."
cargo "$@"
fi
}
run_cargo "$@"
このスクリプトに実行権限を付与しておきます:
chmod +x scripts/run_cargo.sh
3. VSCode 設定の追加
.vscode/settings.json
に以下の設定を追加します:
{
"rust-analyzer.runnables.command": "./scripts/run_cargo.sh"
}
4. データベース接続用のテストコード
src/lib.rs
に以下のようなテストコードを作成します:
#[cfg(test)]
mod tests {
use std::env;
use sqlx::PgPool;
#[tokio::test]
async fn test_database_connection() -> Result<(), Box<dyn std::error::Error>> {
// DATABASE_URL環境変数から接続文字列を取得
let database_url = env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://postgres:password@localhost:5432/testdb".to_string());
let pool = PgPool::connect(&database_url).await?;
// データベースへの接続テスト
let result = sqlx::query!("SELECT 1 as num")
.fetch_one(&pool)
.await?;
assert_eq!(result.num, 1);
Ok(())
}
}
動作確認
- Docker 環境を起動します:
docker compose up -d
- VSCode で
src/lib.rs
を開き、テストコード上にある「▶ Run Test」をクリックします。
テストが Docker 環境内で実行され、データベースに正常に接続できることが確認できました。
仕組み
このセットアップが機能する仕組みを説明します:
- Rust Analyzer は通常、
cargo test
コマンドを直接実行します。 - 設定ファイルで
rust-analyzer.runnables.command
を変更することで、代わりにrun_cargo.sh
を実行するようになります。 - 今回作成した
run_cargo.sh
スクリプトの挙動:- まず、指定された Docker コンテナが実行中かチェックします
- コンテナが実行中の場合、
docker compose exec
を使用してコンテナ内でcargo
コマンドを実行します - コンテナが実行されていない場合、ローカルで
cargo
コマンドを実行します
まとめ
Docker 環境を使用する Rust プロジェクトでも、これらの設定で VSCode のインラインテスト実行機能を快適に使用できるようになります。
特に、データベース接続を必要とするテストケースの実行が容易になり、開発効率の向上が期待できそうです!