【2024 年版】取り入れて良かったツール・技術¶
2024 年に開発環境やテスト基盤へ取り入れて良かったツールとして、uv、Devbox、Testcontainers の 3 つを紹介します。Python のプロジェクト管理、開発環境の構築、ミドルウェアを含むテストと対象がそれぞれ異なるため、ツールごとに特徴と導入して変わった点を以下にまとめます。
uv¶
uvは Rust で書かれた、Python のプロジェクトとパッケージを管理するためのツールです。他のツールと比べて高速に動作するのが特徴で、主な利点は次のとおりです。
- ベンチマーク結果によると pip よりも 10 倍から 100 倍高速に動作する
- pip や pip-tools の代替として使える
- poetry のように、プロジェクト全体の依存関係も管理できる
uv の開発元である Astral 社は、linter の Ruff も開発しています。2024 年の時点で、Ruff のリポジトリで型チェッカー「red knot」の開発が進んでいました(2025 年 5 月にty へ改名)。Python 向けのツールを高速化してきた Astral 社が開発しているため、今後も注目していきたいと考えています。
Python 実行環境のセットアップ¶
これまで pyenv で Python 環境を構築することが多かったのですが、pyenv を動かすには依存関係が多くハマりやすいうえ、ビルドにも時間がかかっていました。uv なら Python Standalone Binary をダウンロードして使うこともできるため、Python 環境の構築が簡単かつ高速になりました。
マルチ環境のロックファイル管理¶
CPU で動かす環境と GPU(CUDA)で動かす環境とで、インストールするパッケージを変えたい場合があります。uv pip compileに複数の requirements ファイルを渡すと、共通のベース依存関係と環境固有の依存関係をまとめて依存解決し、環境ごとのロックファイルを生成できます。
graph TD
base["base_requirements.txt<br/>(共通ライブラリ)"]
cpu_in["cpu_requirements.txt<br/>(CPU 用追加設定)"]
gpu_in["gpu_requirements.txt<br/>(GPU 用追加設定)"]
cpu_out["cpu_locked.txt<br/>(CPU 環境用ロック)"]
gpu_out["gpu_locked.txt<br/>(GPU 環境用ロック)"]
base --> cpu_out
cpu_in --> cpu_out
base --> gpu_out
gpu_in --> gpu_out 共通の依存関係を 1 つのファイルにまとめつつ CPU と GPU の環境の依存関係を分離できるため、ベースを変更するだけで両方の環境の依存関係を一括で更新できます。依存関係を共通化するとキャッシュにヒットしやすくなり、依存解決も短い時間で完了します。
Devbox¶
Devboxは、開発環境を宣言的に構築するためのツールです。CLI のバイナリや開発に必要なソフトウェアをセットアップでき、マシン全体で使うツールとプロジェクトごとに使うツールを分けて管理できます。設定を JSON 形式のファイルに記述するので、このファイルを共有すれば他の開発者も同じ開発環境を再現しやすくなります。
内部でパッケージマネージャの Nix を使っており、豊富なパッケージを利用できます。Nix の構文や仕様を知らなくても CLI から簡単に使えるのが個人的に嬉しい点で、キャッシュ機能によって開発環境を高速に構築できます。
移行前後の比較¶
これまで Homebrew を中心に開発環境を構築していましたが、Devbox へ移行して次のように変わりました。
| 項目 | Homebrew 中心の運用 | Devbox 移行後 |
|---|---|---|
| 開発環境の構築にかかる時間 | 20 分ほど | 数分程度 |
| ホスト環境への影響 | 汚染のリスクがある | 汚染を防げる |
構築時間が短くなって開発効率が向上したうえ、グローバルの環境とプロジェクトごとの環境を分けて管理できるため、ホスト環境を汚染せずに済みます。グローバル環境へ反映する前に、サンドボックス環境でツールを試しやすくなったのも利点です。
Testcontainers¶
Testcontainersは、Docker コンテナで動くものを使い捨てのコンテナとしてテストに提供するオープンソースのライブラリです。データベースやメッセージブローカー、Web ブラウザなどほぼ何でも扱え、データベースやミドルウェアまで含めてテストしたい場面で活用できます。
テストコードの中にコンテナを記述しておくと、テストの実行時に Testcontainers がコンテナの作成から削除までを行います。そのため、モックや複雑な環境設定を用意しなくても、ミドルウェアを含む結合テストを実行できます。多くの言語とテストフレームワークに対応しており、必要なのは Docker だけです。
従来の方法との比較¶
開発マシンへ事前にセットアップする、Docker Compose を使う、別のマシンや環境に接続するといった方法でも、データベースやミドルウェアをモックせずにテストできます。ただし、いずれも環境構築に手間がかかり、ポータビリティにも問題があります。さらに、リソースを共有するためポート競合やデータ汚染でテストがフレイキーになりやすく、実行時間も長くなりがちです。Testcontainers を使う場合との違いは次のとおりです。
| 項目 | 従来の方法 | Testcontainers |
|---|---|---|
| 環境の用意 | テストの前に構築しておく | テスト実行時に必要なコンテナを起動する |
| リソース | 複数のテストで共有する | 使い捨てのコンテナを使う |
| 動かせる場所 | 用意した環境に依存する | Docker があれば動く |
Testcontainers によって再現可能な環境でテストしやすくなり、1 台のマシンでテストを完結できる範囲が広がったことで、ミドルウェアを含む結合テストにも取り組みやすくなりました。
まとめ¶
対象こそ異なるものの、uv、Devbox、Testcontainers のいずれも環境を再現しやすくし、構築にかかる手間や時間を減らしてくれました。
- uv:Python 環境の構築とパッケージの依存解決の高速化
- Devbox:ホストを汚染しない開発環境の構築と共有
- Testcontainers:ミドルウェアを含むテスト環境の用意と使い捨て
開発マシンのセットアップからミドルウェアを含むテストまで、環境構築の手間や環境差異によるトラブルを減らしたい場面では、良い選択肢になりそうです。