Rust はコンパイラ自体が強力な品質ゲートとして機能しますが、それだけに留まらず、エコシステムには多種多様な品質保証ツールが揃っています。本記事では lint・フォーマット・テスト・カバレッジ・セキュリティ監査など、実務で使える主要ツールを体系的に解説します。
Linter / フォーマッター
rustfmt
rustfmt は Rust 公式のコードフォーマッターです。cargo fmt で呼び出せます。
# フォーマット適用
cargo fmt
# 差分確認のみ(CI 向け)
cargo fmt --check
プロジェクトルートに rustfmt.toml を置くことでスタイルをカスタマイズできます。
# rustfmt.toml
edition = "2021"
max_width = 100
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
CI では cargo fmt --check を組み込み、フォーマット差分があればビルドを失敗させるのが定石です。
Clippy
Clippy は Rust 公式の lint ツールで、200 以上のリントルールを持ちます。cargo clippy で実行します。
# 基本実行
cargo clippy
# すべての lint を警告として扱う
cargo clippy -- -W clippy::all
# pedantic カテゴリも有効化
cargo clippy -- -W clippy::pedantic
Clippy のリントはカテゴリで分類されており、重要度や目的が異なります。
| カテゴリ | 内容 |
|---|---|
correctness |
バグになり得るコード(デフォルト: deny) |
suspicious |
意図が疑わしいパターン |
style |
慣用的な書き方への誘導 |
perf |
パフォーマンス改善の提案 |
pedantic |
厳格なスタイル(オプトイン) |
nursery |
実験的なリント(オプトイン) |
#[allow(...)] や #[warn(...)] でファイル・関数単位の制御もできますが、deny をファイル先頭に書いてプロジェクト全体を厳格に保つ方法も有効です。
#![deny(clippy::all)]
#![warn(clippy::pedantic)]
型システムと静的解析
Rust コンパイラ(rustc)
Rust のコンパイラ自体が最強の静的解析ツールです。型安全・所有権チェック・借用チェッカーにより、null 参照・データ競合・メモリ解放後使用といったバグをコンパイル時に検出します。cargo check を使うとリンクをスキップして型チェックだけを高速に実行できます。
# リンクせず型チェックのみ(通常の build より速い)
cargo check
rust-analyzer
rust-analyzer は LSP(Language Server Protocol)実装で、エディタでのリアルタイム解析を担います。インレイヒント・コード補完・リファクタリング支援などを提供し、VS Code や Neovim などの主要エディタで利用できます。
インストールは rustup component add rust-analyzer で完了します。
MIRI
MIRI は Rust の MIR(Mid-level Intermediate Representation)インタプリタで、unsafe コードの未定義動作を検出します。通常のコンパイラでは検出できない out-of-bounds アクセスや不正なポインタ操作をランタイムで発見します。
rustup component add miri
cargo miri test
unsafe を多用するクレートや FFI 境界を持つコードの検証に特に効果的です。
テスト
cargo test
Rust 標準のテストランナーです。ユニットテスト・統合テスト・ドクテストをすべてカバーします。
// ユニットテスト(同じファイル内)
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
#[should_panic(expected = "overflow")]
fn test_overflow() {
add(i32::MAX, 1);
}
}
統合テストは tests/ ディレクトリに配置します。ドクテストはドキュメントコメント内の ```rust ブロックが自動的にテストとして実行されます。
# すべてのテストを実行
cargo test
# 特定のテスト名でフィルタ
cargo test test_add
# ドクテストのみ
cargo test --doc
cargo-nextest
cargo-nextest は高速な並列テストランナーです。標準の cargo test より大幅に速く、テスト結果の表示も見やすくなります。
cargo install cargo-nextest
cargo nextest run
JUnit XML 形式でレポート出力できるため、CI との統合にも向いています。
proptest / quickcheck
proptest や quickcheck はプロパティベーステストを実現するクレートです。手動でテストケースを書く代わりに「この性質が常に成り立つ」という命題をランダム生成された入力で検証します。
use proptest::prelude::*;
proptest! {
#[test]
fn test_sort_idempotent(mut v: Vec<i32>) {
v.sort();
let first = v.clone();
v.sort();
prop_assert_eq!(first, v);
}
}
エッジケースの発見に特に強く、境界値を手動で列挙する手間を省けます。
カバレッジ
cargo-llvm-cov
cargo-llvm-cov は LLVM のソースベースカバレッジ計測を使ったカバレッジツールです。HTML レポートの生成や lcov 形式への出力が可能です。
cargo install cargo-llvm-cov
rustup component add llvm-tools-preview
# HTML レポートをブラウザで開く
cargo llvm-cov --open
# lcov 形式で出力(Codecov 等と連携)
cargo llvm-cov --lcov --output-path lcov.info
tarpaulin
tarpaulin は Linux 向けのカバレッジツールです。ptrace を利用するため Linux 専用ですが、設定が簡単です。
cargo install cargo-tarpaulin
cargo tarpaulin --out Html
macOS では cargo-llvm-cov を選ぶのが現状の定番です。
セキュリティ・依存関係
cargo-audit
cargo-audit は RustSec Advisory Database を参照して、依存クレートの既知脆弱性をスキャンします。
cargo install cargo-audit
cargo audit
CI に組み込んでおくと、依存関係に新しい脆弱性が登録されたタイミングでビルドを失敗させられます。
cargo-deny
cargo-deny は依存関係のポリシー管理ツールです。使用を禁止するライセンス・クレート・重複バージョンの制限をルールとして定義します。
cargo install cargo-deny
cargo deny check
設定ファイル deny.toml でポリシーを宣言します。
# deny.toml
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-2-Clause"]
[bans]
multiple-versions = "warn"
cargo-geiger
cargo-geiger は依存グラフ全体にわたる unsafe コードの使用量を可視化します。unsafe を完全に排除できなくても、どのクレートがリスクの源かを把握するのに役立ちます。
cargo install cargo-geiger
cargo geiger
その他の便利ツール
cargo-expand
cargo-expand はマクロを展開した後のコードを表示します。デバッグや、derive マクロが生成するコードの確認に欠かせません。
cargo install cargo-expand
cargo expand
cargo-udeps
cargo-udeps は Cargo.toml に宣言されているが実際には使われていない依存クレートを検出します。nightly ツールチェーンが必要です。
cargo install cargo-udeps
cargo +nightly udeps
cargo-bloat
cargo-bloat はバイナリサイズに対してどの関数・クレートが寄与しているかを分析します。リリースビルドのサイズ最適化に使います。
cargo install cargo-bloat
cargo bloat --release --crates
CI 統合のヒント
justfile での組み合わせ
just はシンプルなタスクランナーで、複数ツールの呼び出しを一元管理できます。
# justfile
check:
cargo fmt --check
cargo clippy -- -D warnings
cargo test
cargo audit
ci: check
cargo llvm-cov --lcov --output-path lcov.info
GitHub Actions 設定例
name: CI
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy, llvm-tools-preview
- name: Format check
run: cargo fmt --check
- name: Clippy
run: cargo clippy -- -D warnings
- name: Test
run: cargo test
- name: Audit
run: |
cargo install cargo-audit
cargo audit
- name: Coverage
run: |
cargo install cargo-llvm-cov
cargo llvm-cov --lcov --output-path lcov.info
dtolnay/rust-toolchain アクションを使うと rust-toolchain.toml のバージョン固定とも相性が良く、components でまとめてインストールできます。
まとめ
Rust の品質保証ツールを整理すると次の通りです。
| 目的 | ツール |
|---|---|
| フォーマット | rustfmt(cargo fmt) |
| Lint | Clippy(cargo clippy) |
| 型チェック(高速) | cargo check |
| Unsafe 検証 | MIRI |
| テスト | cargo test、cargo-nextest |
| プロパティテスト | proptest、quickcheck |
| カバレッジ | cargo-llvm-cov、tarpaulin |
| 脆弱性スキャン | cargo-audit |
| 依存ポリシー | cargo-deny |
| unsafe 可視化 | cargo-geiger |
| マクロ展開確認 | cargo-expand |
| 未使用依存 | cargo-udeps |
| バイナリ解析 | cargo-bloat |
コンパイラ自体の強力な保証を基盤にしつつ、これらのツールを CI に組み込むことで、Rust プロジェクトの品質を高い水準に維持できます。まずは cargo fmt --check + cargo clippy -- -D warnings + cargo test + cargo audit の 4 つを GitHub Actions に追加するところから始めてみてください。