iT邦幫忙

2023 iThome 鐵人賽

DAY 30
0

今天是這次鐵人賽的尾聲

我們要再來介紹 Rust 中的測試

昨天介紹的測試是單元測試,不過還要再另外補充 private method 的測試

private method 測試

不曉得各位在測試的時候會不會測 private method ,有些人覺得需要,有些人可能覺得不用

不管需不需要, Rust 是可以支援 private method 測試的

跟其他的單元測試都是一樣,一樣要標註 test 屬性

我們來試試


fn calculator_private(a: i32, b: i32) -> i32 {
    let result = a + b;
    result
}

#[cfg(test)]
mod tests {
    use super::calculator_private;

    #[test]
    fn calculator_test() {
        assert_eq!(4, calculator_private(2, 2));
    }
}
> cargo test

     Running unittests src/main.rs (target/debug/deps/hello_world-9a6d4baccdd90e29)

running 1 test
test tests::internal ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

整合測試

在 Rust 中,會把整合測試放在 tests 目錄底下

Cargo 會自動搜尋 tests 底下的測試文件

所以我們也不需要用 #[cfg(test)] 告訴 Cargo 這個是測試檔案了

我來把昨天的測試搬到 tests 檔案底下,tests 要與 src 平行 (放在根目錄底下)

# tests/calculator_test.rs

#[test]
fn test_addition() {
    let result = calculator::addition(1, 2);

    assert!(result.eq(&3), "你的運算結果不等於 {}", 4)
}

跑測試下去,錯了,他找不到 calculator 這個 module

> cargo test

error[E0433]: failed to resolve: use of undeclared crate or module `calculator`
 --> tests/calculator_test.rs:5:18
  |
5 |     let result = calculator::addition(1, 2);
  |                  ^^^^^^^^^^ use of undeclared crate or module `calculator`

那我們用 use 把他加進來看看

use hello_world::calculator;

#[test]
fn test_addition() {
    let result = calculator::addition(1, 2);

    assert!(result.eq(&3), "你的運算結果不等於 {}", 4)
}

這次跑下去還是錯了,不過錯誤訊息更清楚了,他寫著,他在根目錄找不到 calculator 這個 module

> cargo test

error[E0432]: unresolved import `hello_world::calculator`
 --> tests/calculator_test.rs:1:5
  |
1 | use hello_world::calculator;
  |     ^^^^^^^^^^^^^^^^^^^^^^^ no `calculator` in the root

For more information about this error, try `rustc --explain E0432`.

這是因為我們把 calculator 放在 main.rs 中了

在 Rust 中,

main.rs 是用來執行程式碼的,

lib.rs 才是用來放功能程式碼的,

而我們測試應該都是測功能,應該將功能程式碼放在 lib.rs 中才對

# src/lib.rs

pub mod calculator {
    pub fn addition(a: i32, b: i32) -> i32 {
        let result = a + b;
        result
    }
}

我們可以看到下面這一串

編譯的時候會去看整個專案中的測試

首先是看 src/lib.rs 中的測試
其次是看 src/main.rs 中的測試
最後是看 tests 中的測試

單元測試都會放在 src/lib.rs 以及 src/main.rs

而跨模組或者功能性的整合測試,就會放在 tests

> cargo test

     Running unittests src/lib.rs (target/debug/deps/hello_world-a01c1fd1ce8393ba)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/main.rs (target/debug/deps/hello_world-9a6d4baccdd90e29)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running tests/calculator_test.rs (target/debug/deps/calculator_test-77b32a48a24a9faf)

running 1 test
test test_addition ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests hello_world

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

測試判斷

Rust 也提供了很多的測試的評估方法

像是我們昨天用到的 assert! assert_eq!

今天我們再多來介紹 1 個 以及 debug 模式下執行的評估方法

assert_ne!

判斷兩者之間的值是否不相等,以剛剛的例子來看

如果我們把第一個參數改成 4 ,就會失敗,改成 4 以外的值,就會成功

fn calculator_private(a: i32, b: i32) -> i32 {
    let result = a + b;
    result
}

#[cfg(test)]
mod tests {
    use super::calculator_private;

    #[test]
    fn internal() {
        assert_ne!(5, calculator_private(2, 2));
    }
}

Debug 模式下的測試評估方法

我們在什麼時候會需要在 Debug 模式下跑測試呢

而他們的用法跟 assert! assert_eq! assert_ne! 沒有什麼不同

我們可以直接在開發模式知道測試的結果,跟 test 模式不一樣的是,他只會運行 main.rs 裡面的程式碼

且在 release 的時候不會運行

fn main() {
    fn calculator_private(a: i32, b: i32) -> i32 {
        let result = a + b;
        result
    }

    debug_assert_eq!(5, calculator_private(1, 2));
}

上一篇
Day 29 - 單元測試
系列文
成為程式界的 F1 賽車手,用 30 天認識 Rust 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言