跳转至

控制测试运行

一、概述

cargo testcargo run命令类型,cargo test会在测试模式下编译代码,并生成一个二进制可执行文件,该二进制可执行文件用于测试。我们可以通过添加参数来改变cargo test的行为,如果不添加任务参数,rust将会执行默认的测试行为。默认行为如下

  • 并行测试
  • 执行所有测试
  • 捕获(不显示)所有输出,只会输出测试失败的相关输出,使读取与测试结果相关的输出更容易

命令行参数如下

  • 针对cargo test的参数:紧跟在 cargo test 之后,使用cargo test --help查看所有参数列表
  • 针对测试可执行程序:放在 -- 之后,使用cargo test -- --help查看所有参数列表

二、并行运行测试

在默认情况下,使用多线程并行运行多个测试。这样运行更快,我们更早得的到反馈。但由于是并行运行,所以我们要确保运行的过程中不回相互依赖,而且不依赖某个共享的状态(环境、工作目录、环境变量等等)。因为如果两测试如果共享一个状态,其中一个测试运行完成的之后把某个状态修改了,将会影响另一个测试。

如果我们不想并行运行测试,或者希望精确控制测试时,所启用的线程的数量,那么就可以传递该参数。该参数传递给二进制文件,可以使用--test-threads参数,后面跟着线程的数量,例如:cargo test -- --test-threads=1

这样的话,如果执行多个测试,相比默认情况下它会耗费更多的时间,但是它试顺序执行的。如果多个测试使用共享状态,在该模式下运行,出现状态干扰的情况将被减少。

三、显式函数的输出

默认情况下,如果测试通过,Rust的test库会捕获所有打印到标准输出的内容,即所有打印到标准输出的内容不会显示了。例如:如果被测试的代码中用到了println!。如果测试通过,将不会在终端看到println!打印的内容。如果测试失败,将会看到println!打印的内容和失败信息。

如果我们想让测试通过的时候也把println!的输出内容也打印出来,就需要加一个参数--shou-output,最终执行命令为cargo test -- --show-output

四、按名称运行测试的子集

选择运行测试是将测试的名称(一个或多个)作为cargo test的参数。如下例子

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

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

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

    #[test]
    fn add_three_and_two() {
        assert_eq!(5, add_two(3));
    }

    #[test]
    fn one_hundred() {
        assert_eq!(102, add_two(100));
    }
}

在以上代码中,一共包含了三个测试,如果我们直接使用cargo test命令,将会运行所有的测试。如果只想运行一个测试,我们直接把测试的名称作为cargo test的参数即可。如cargo test one_hundred

但是,有时候我们需要运行多个测试,则需要指定测试名(模块名也可以)的一部分,这样任何匹配这个名称都会被执行。如在上列示例代码中,我们使用cargo test add命令将会执行前两个测试函数,我们使用cargo test tests命令将会执行tests模块中所有的测试函数。

五、忽略测试

我们可以通过参数实现忽略某些测试,运行剩余的测试。有些情况下,我们不希望运行一些耗时的测试,则可以通过ignore属性来对要忽略的测试函数进行标记,如下示例

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(4, 2 + 2);
    }

    #[test]
    #[ignore]
    fn expensive_test() {
        assert_eq!(5, 1 + 1 + 1 + 1 + 1);
    }
}

通过默认的测试命令,rust将会忽略有ignore标记的测试函数,如果我们希望单独运行ignore标记的测试函数,则需添加--ignored参数,最终执行命令为cargo test -- --ignored