Rust Tests

Table of Contents

1. Rust Tests

1.1. writing tests

1.1.1. unit test

  1. unit test case 直接放在要测试的 mod 中, 所以它可以访问 mod 的私有成员.
  2. 习惯上, 把 test 放在一个 tests mod 中, 但这不是必需的.
  3. 通过 `#[cfg(test)]` 告诉编译器只有在 cargo test 时才编译 test case. 但如果不指定 `#[cfg(test)]`, cargo build 时会警告 `test_add` 没有被调用, 所以最终也不会编译 `test_add`. 所以 `#[cfg(test)]` 不是必需的
  4. 每个 test case 前需要加 `#[test]`, 这样 cargo test 时能会执行该函数
  5. assert!, assert_eq!, assert_ne! 宏
  6. 正常情况下函数 pannic 表示 test fail, 通过 `#[should_panic]` 反之
  7. test case 可以返回一个 `Result` 表示测试结果
pub fn times(a: i32, b: i32) -> i32 {
    let mut ret = 0;
    for _ in 0..a {
        ret += b;
    }
    ret
}

fn add(a: i32, b: i32) -> i32 {
    a + b
}
fn do_panic() -> () {
    panic!("paniced");
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_add() {
        assert_eq!(super::add(2, 2), 4);
        assert!(super::add(2, 3) == 5);
        assert_ne!(crate::add(1, 2), 2);
        assert_eq!(super::add(1, 2), 3, "failed...");
    }

    #[test]
    #[should_panic]
    fn test_panic() -> () {
        super::do_panic();
    }

    #[test]
    fn test_add_with_result() -> Result<(), String> {
        let x = super::add(2, 2);
        if super::add(2, 2) == 4 {
            Ok(())
        } else {
            Err("2+2 should be 4".to_owned())
        }
    }
}

1.1.2. integration test

integration test 的布局:

/home/sunway/hello
├── Cargo.lock
├── Cargo.toml
├── src
│   └── lib.rs
└── tests
    ├── test_fact.rs
    └── test_times.rs

其中 tests 目录下的 `test_fact.rs` 和 `test_times.rs` 是 integration test case.

由于它们和 hello 是不同的 mod, 所以 integration test case 只能测试 hello 中 pub 的 method.

1.2. running tests

  1. `cargo test` 执行所有 test case
  2. `cargo test add` 执行所有名称与 `add` 匹配的 test case
  3. `cargo test – –test-threads=1` 所有 test case 串行执行

Author: [email protected]
Date: 2019-02-13 Wed 00:00
Last updated: 2024-08-05 Mon 17:55

知识共享许可协议