rust 自动化测试

2022-06-09  本文已影响0人  book_02

1. 参考

https://kaisery.github.io/trpl-zh-cn/ch11-03-test-organization.html
https://course.rs/test/unit-integration-test.html

2. 前置说明

测试分类:

  1. 单元测试(unit tests)
  2. 集成测试(integration tests)

单元测试:

  1. 一次测试某一个代码单元(一般都是函数)
  2. 或者是测试私有接口
  3. 验证该单元是否能按照预期进行工作

集成测试:

  1. 测试公有接口
  2. 可能会测试多个模块
  3. 与其他外部代码一样

3. 单元测试

假设建立了一个adder工程

cargo new adder

cd adder

3.1 测试函数

单元测试的惯例是将测试代码的模块跟待测试的正常代码放入同一个文件中,例如src/lib.rs 文件中有如下代码:

pub fn add_two(a: i32) -> i32 {
    a + 2
}

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

    #[test]
    fn it_works() {
        assert_eq!(add_two(2), 4);
    }
}

说明:

  1. it_worksadd_two进行测试
  2. #[cfg(test)] 标注告诉 Rust 只有在 cargo test 时才编译和运行模块 tests
  3. #[cfg(test)]中,cfg是配置configuration的缩写,它告诉Rust:当test配置项存在时,才运行下面的代码
  4. cargo test在运行时,就会将test这个配置项传入进来
  5. #[test]标注表明下面的函数是测试用例函数,没加#[test]标注的函数就是普通函数,不算作一个测试用例
  6. 使用 use super::*;tests 的父模块中的所有内容引入到当前作用域中

3.2 测试私有函数

修改src/lib.rs 文件如下:

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

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

    #[test]
    fn internal() {
        assert_eq!(4, internal_adder(2, 2));
    }
}

说明:

  1. internal对私有函数internal_adder进行测试
  2. internal_adder 并没有使用 pub 进行声明,因此它是一个私有函数
  3. 很多语言无法对私有函数直接进行测试,Rust允许测试私有函数

4. 集成测试

说明:

  1. 与单元测试在同一个文件不同,集成测试的代码是在一个单独的目录下,为tests目录
  2. 集成测试只能调用通过 pub 定义的函数
  3. 跟外部模块一样的方式调用要测试的代码
  4. 之所以有集成测试,是因为单元测试的通过,并不意味着集成测试就能通过

tests目录说明:

  1. tests 目录在根目录下
  2. Cargo 会自动来此目录下寻找集成测试文件
  3. 在运行 cargo test 时,对tests目录中的每个文件都进行编译运行
  4. tests目录下的子目录中的文件不会被当作独立的包

4.1 集成测试的例子

创建一个集成测试文件 tests/integration_test.rs

use adder;

#[test]
fn it_adds_two() {
    assert_eq!(4, adder::add_two(2));
}

说明:

  1. it_adds_twoadder::add_two进行测试
  2. 无需再使用 #[cfg(test)] 标注,在tests目录下就说明了是测试模块

4.2 公共模块

有时tests目录下各个集成测试文件需要使用公共的功能(比如setup),
用于状态初始化,然后多个测试包都需要使用该函数进行状态的初始化。

如果创建tests/common.rs文件,那么改文件里的函数被当作集成测试函数运行,没有达到公公模块的功能。

Rust允许通过如下方式来使用公共模块
创建 tests/common/mod.rs 文件:

pub fn setup() {
    // ...
}

然后修改tests/integration_test.rs如下:

use adder;

mod common;

#[test]
fn it_adds_two() {
    common::setup();
    assert_eq!(4, adder::add_two(2));
}

说明:

  1. tests目录下的子目录中的文件不会被当作独立的包
  2. 通过mod common的方式来声明common模块

5. cargo test 说明

5.1 结果说明

运行cargo test,可以看到如下输出:

     Running unittests (target/debug/deps/adder-054c4fd663c7aecd)

running 2 tests
test tests::internal ... ok
test tests::it_works ... ok

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

     Running unittests (target/debug/deps/adder-e0abdd530a4014d2)

running 0 tests

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

     Running tests/integration_test.rs (target/debug/deps/integration_test-9155f1efa73dd15e)

running 1 test
test it_adds_two ... ok

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

   Doc-tests adder

running 0 tests

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

说明:

  1. 测试内容有三个部分:单元测试,集成测试和文档测试

5.2 运行指定测试用例

可以通过指定名称的方式来运行特定的集成测试用例:

cargo test --test integration_test

单元测试、文档测试啥的都没有运行,只有集成测试目录下的 integration_test 文件被顺利执行

上一篇下一篇

猜你喜欢

热点阅读