本文へスキップ
BecomeCoder

Rustコース · 第12章 プロジェクトとツール · レッスン47

テスト ― #[test]・cargo test・assert!

ブラウザで完結

導入

「動いているつもり」のコードが、実は間違っていた——というのはどの言語でもよくある話です。Rust では、外部のテストフレームワークを別途入れなくても、言語とツールチェーンに最初からテストの仕組みが同梱されています。だからこそ実務のRustプロジェクトでは、テストを書くハードルがとても低くなっています。

説明

テストの核になるのが assert! 系のマクロです。条件が満たされなければ、その場でパニックしてテストが失敗したと知らせてくれます。

fn add(a: i32, b: i32) -> i32 {
    a + b
}

fn is_even(n: i32) -> bool {
    n % 2 == 0
}

fn main() {
    assert_eq!(add(2, 3), 5);      // 左辺と右辺が等しいことを確認
    assert_eq!(add(-1, 1), 0);
    assert!(is_even(4));            // 条件が true であることを確認
    assert!(!is_even(7));
    // assert_ne!(add(1, 1), 3);    // 左辺と右辺が異なることを確認(今回は省略)

    println!("all tests passed");
}
  • assert_eq!(実際の値, 期待する値) … 一致しなければ、両方の値を表示してパニックします。値を突き合わせる一番よく使う形です。
  • assert!(条件) … 条件が false ならパニックします。真偽値を確認したいときに使います。
  • assert_ne!(a, b)ab が等しくないことを確認します(assert_eq! の逆)。

実際のRustプロジェクトでは、こうしたチェックを main の中に埋め込むのではなく、#[test] を付けた専用の関数として書きます。

fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[test]
fn test_add_positive() {
    assert_eq!(add(2, 3), 5);
}

#[test]
fn test_add_negative() {
    assert_eq!(add(-1, 1), 0);
}

#[test] を付けた関数は、通常の実行(cargo run)では呼ばれず、cargo test を実行したときにだけ集めて実行されます。全部パスすれば test result: ok、失敗したテストがあれば FAILED とその内容が表示されます。1つのファイルの中に何個でも #[test] 関数を書けるので、機能を作るたびにテストも一緒に増やしていくのが実務の流儀です。

補足:このコースの実行環境fn main を直接動かす学習用シミュレータなので、#[test] 関数は自動では実行されません。実際の挙動を体験するには、上のコードのように main の中で assert_eq!/assert! を直接呼んで確認します。本物のプロジェクトでは #[test]cargo test の形で書くのが基本だと覚えておいてください。

やってみよう

下のエディタで addis_even の実装を意図的に間違えてみて、assert_eq!/assert! がどのパニックメッセージを出すか確かめてみましょう。

演習

n を受け取り2乗した値を返す関数 square(n: i32) -> i32 を定義してください。assert_eq!square(3)9 に、square(-4)16 になることを確認し、両方成功したら println!("ok") と出力してください。

ヒント1を見る

fn square(n: i32) -> i32 { n * n } のように定義します。

ヒント2を見る

assert_eq!(square(3), 9); assert_eq!(square(-4), 16);main の中で呼んだ後、println!("ok"); します。

実際に動かしてみよう

下のエディタにRustを書いて「実行」を押すと、学習用シミュレータが println! の出力を表示します(本物のrustcではなく、教材の範囲を再現した軽量エンジンです)。struct・enum・match・トレイト・Vec/String/HashMap・Option/Result なども動きます。本文の例を書き換えて動かしてみましょう(所有権・借用チェッカーのコンパイルエラーは再現しないため、動きの確認用として使ってください)。

Rust — ブラウザ内で実行(学習用シミュレータ)

Rustの教材サブセットを動かす学習用シミュレータを読み込みます(本物のrustcではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。