Rustある条件下でpanic
sの関数があり、その関数がパニック状態になっているかどうかを検証するためのテストケースを作成したいと思います。 _assert!
_および_assert_eq!
_マクロ:これをテストするためのメカニズムはありますか?
新しいタスクを生成し、そのタスクがパニックになるかどうかを確認できます。理にかなっていますか?
私の場合、_Result<T, E>
_を返すのは適切ではありません。
実装しているAdd
型にMatrix
特性のサポートを追加したいと思います。このような追加の理想的な構文は次のようになります。
_let m = m1 + m2 + m3;
_
ここで、_m1
_、_m2
_、_m3
_はすべて行列です。したがって、add
の結果タイプはMatrix
でなければなりません。次のようなものはわかりにくいでしょう。
_let m = ((m1 + m2).unwrap() + m3).unwrap()
_
同時に、add()
関数は、追加される2つの行列の次元が同じであることを検証する必要があります。したがって、次元が一致しない場合、add()
はパニックする必要があります。利用可能なオプションはpanic!()
です。
答えは、Rust本の testing セクションにあります。具体的には、#[should_panic]
属性:
#[test]
#[should_panic]
fn test_invalid_matrices_multiplication() {
let m1 = Matrix::new(3, 4); // assume these are dimensions
let m2 = Matrix::new(5, 6);
m1 * m2
}
FrancisGagnéが答えで述べたように、_#[should_panic]
_属性は、より複雑なテストには十分にきめ細かくないこともわかります。たとえば、何らかの理由でテストのセットアップが失敗した場合(つまり、テスト)、Idoパニックを失敗と見なしたい!
Rust 1.9.0、 std::panic::catch_unwind()
が利用可能になりました。これにより、パニックが発生する可能性のあるコードをクロージャに入れることができます。 thatコードによって発せられたパニックは、期待される(つまり、テストに合格した)と見なされます。
_#[test]
fn test_something() {
... //<-- Any panics here will cause test failure (good)
let result = std::panic::catch_unwind(|| <expected_to_panic_operation_here>);
assert!(result.is_err()); //probe further for specific error type here, if desired
}
_
巻き戻さないパニックをキャッチできないことに注意してください(例:std::process::abort()
)。
テスト関数の特定の部分のみが失敗することを表明したい場合は、 std::panic::catch_unwind()
を使用し、Err
、たとえば is_err()
で。複雑なテスト機能では、これにより、早期の失敗が原因でテストが誤ってパスしないようにすることができます。
補遺として:@ U007Dが提案するソリューションは、doctestでも機能します。
/// My identity function that panic for an input of 42.
///
/// ```
/// assert_eq!(my_crate::my_func(23), 23);
///
/// let result = std::panic::catch_unwind(|| my_crate::my_func(42));
/// assert!(result.is_err());
/// ```
pub fn my_func(input: u32) -> u32 {
if input == 42 {
panic!("Error message.");
} else {
input
}
}