1. 程式人生 > 實用技巧 >Rust基礎學習筆記(二):自動測試

Rust基礎學習筆記(二):自動測試

本文介紹Rust的自動測試機制。

如何編寫測試

測試是一些用來確定程式碼正常執行的函式。通過對一些數值運算後得到預期的結果來實現。

Rust中可以用test屬性、一些巨集和should_panic屬性編寫。

分析Test函式

在測試函式前面一行應有宣告#[test],如下:

//File name: src/lib.rs
#[cfg(test)]
mod tests {
    #[test]
    fn it_works(){
        assert_eq!(2 + 2, 4);
    }
}
$ cargo test
   Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.72s Running target/debug/deps/adder-92948b65e88960b4 running 2 tests test tests::another ... FAILED  //顯示another失敗 test tests::exploration ... ok  //顯示exploaration成功 failures: ---- tests::another stdout ---- thread 'main' panicked at 'Make this test fail
', src/lib.rs:10:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. failures: tests::another  //僅顯示失敗資訊,最終編譯不通過 test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--lib'

這個資訊在編譯行輸入$cargo test時輸出,表明只有在這種情況下才會編譯#[test]

標記的內容

還有類似measure test、Doc-tests 的內容,留作以後討論

assert!巨集的使用

assert!的引數是一個布林表示式,如果返回了true,測試通過並無事發生;而若返回了false,測試失敗導致報錯。

如下:

#[test]
    fn smaller_cannot_hold_larger() {
        let larger = Rectangle    {
            width: 8,
            height: 7,
        };
        let smaller = Rectangle {
            width:5,
            height:1,
        }
        assert!(!smaller.can_hold(&larger));
)

預期值(expected)--> 左值(left)

實際值(actual)  -->右值(right)

同時有assert_eq!()相等與assert_ne!()不等的差別。後者用於排除非法情況。

這些巨集通過debug格式輸出引數,因此被比較的值必須包括PartialEqDebug這兩個特性。這兩個特性普遍為原生型別與標準庫中的型別所擁有。而對於自定義型別則須在定義前面加上

#[derive(ParitalEq, Debug)]

同時可以通過新增引數來對測試失敗時的返回值進行自定義:

#[test]
fn greeting_contains_name(){
    let result = greeting("Carol");
    assert!(
        result.contains("Carol"),
        "Greeting didn't contain name, value was `{}`",
        result
     );
}

這個時候就會在"panicked at"欄位顯示自定義的內容

should_panic的使用

簡而言之就是把一個應該引起panic的函式加上對應的屬性,使得其在正常編譯的時候反而報錯。這個屬性可以擁有自己的值,在只有引起相應異常的時候才予以通過:

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    #[should_panic(expected = "Guess too Large!"]
    fn greater_than_100(){
        Guess::new(200);
    }
}

在測試函式中運用Result<T, E>作為返回值

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() -> Result<(), String> {
        if 2 + 2 == 4 {
            Ok(())
        } else {
            Err(String::from("two plus two does not equal four"))
        }
    }
}

(困了,待續)