Rust的控制测试如何运行

我爱海鲸 2024-03-16 21:11:17 rust学习

简介控制测试如何运行

1、控制测试如何运行

改变cargo test的行为:添加命令行参数

默认行为:

   并行运行

   所有测试

   捕获(不显示)所有输出,使读取与测试结果相关的输出更容易。

命令行参数:

   针对cargo test的参数:紧跟cargo test后

   针对测试可执行程序:放在--之后

显示帮助:cargo test --help

显示可以使用在两个横线之后的参数:cargo test -- --help

2、并行/连续运行测试

   并行运行测试

运行多个测试:默认使用多个线程并行运行。

运行快

确保测试之间:

-不会互相依赖

-不依赖于某个共享状态(环境、工作目录、环境变量等等)

--test-threads参数

传递给二进制文件

不想以并行方式运行测试,或想对线程数进行细粒度控制

可以使用--test-threads参数,后边跟着线程的数量

例如: cargo test -- --test-threads=1

显式函数输出

默认,如测试通过,Rust的 test库会捕获所有打印到标准输出的内容。

例如,如果被测试代码中用到了println!:

如果测试通过:不会在终端看到println!打印的内容

如果测试失败:会看到printIn!打印的内容和失败信息

fn prints_and_returns_10(a:i32)->i32 {
    println!("I got the value {}",a);
    10
}

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

    #[test]
    fn this_test_will_pass() {
        let value = prints_and_returns_10(4);
        assert_eq!(10,value);
    }

    #[test]
    fn this_test_will_fail() {
        let value = prints_and_returns_10(8);
        assert_eq!(5,value);
    }

}

上面的代码直接运行cargo test通过的函数不会打印pri的内容,失败的才会打印,如果想通过的也打印pri的内容,我们可以加两个参数

cargo test -- --show-output

这样通过的也能打印了

3、按名称运行测试

按名称运行测试的子集

选择运行的测试:将测试的名称(一个或多个)作为cargo test的参数

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

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

    #[test]
    fn add_two_add_two() {
        let value = add_two(2);
        assert_eq!(4,value);
    }

    #[test]
    fn add_three_add_two() {
        let value = add_two(3);
        assert_eq!(5,value);
    }

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

}

cargo test one_hundred

我们使用cargo test 【测试函数的名称】就可以控制测试哪一个函数了

运行多个测试:指定测试名的一部分(模块名也可以)

cargo test add

我们是前缀是add的函数运行就能成功运行前面两个测试函数

cargo test tests

也可以使用模块名tests来进行测试

忽略测试

忽略某些测试,运行剩余测试

ignore属性( attribute)

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

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

}

运行cargo test 就会忽略第二个测试函数

如果我想单独运行第二个被忽略的函数要怎么弄呢?我们可以直接运行

cargo test -- --ignored

4、测试的组织

测试的分类

Rust 对测试的分类:

   单元测试

   集成测试

单元测试:

   小、专注

   一次对一个模块进行隔离的测试

   可测试private接口

集成测试:

   在库外部。和其它外部代码一样使用你的代码

   在库外部。和其它外部代码一样使用你的代码

   只能使用public接口

   可能在每个测试中使用到多个模块

#[cfg(test)]标注

tests模块上的#[cfg(test)]标注:

   一只有运行cargo test才编译和运行代码

   运行cargo build 则不会

集成测试在不同的目录,它不需要#[cfg(test)]标注

cfg: configuration(配置)

一告诉Rust下面的条目只有在指定的配置选项下才被包含

配置选项test:由Rust提供,用来编译和运行测试。

只有cago test才会编译代码,包括模块中的helper函数和#[test]标注的函数

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

}

测试私有函数

Rust允许测试私有函数

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

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

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

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

}

5、集成测试

在Rust里,集成测试完全位于被测试库的外部

目的:是测试被测试库的多个部分是否能正确的一起工作

集成测试的覆盖率很重要

tests目录

创建集成测试: tests目录

tests目录下的每个测试文件都是单独的一个crate

需要将被测试库导入

无需标注#[cfg(test)],tests目录被特殊对待

只有cargo test,才会编译tests目录下的文件

lib.rs:

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

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

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

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

}

tests目录下的测试文件intregration_test.rs:

use demo;

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

运行cargo test即可

运行指定的集成测试

运行一个特定的集成测试:cargo test 函数名

运行某个测试文件内的所有测试: cargo test --test 文件名

another_test.rs:

use demo;

#[test]
fn it_really_adds_two() {
    assert_eq!(4,demo::add_two(2))
}

运行:

cargo test --test intregration_test

这样就只会运行intregration_test文件下的集成测试

集成测试中的子模块

tests 目录下每个文件被编译成单独的crate

这些文件不共享行为(与src下的文件规则不同)

我们在tests目录下建立一个字目录common,这样我们来运行的时候common下的mod.rs就不会当成一个集成测试的文件了

那么我们如何在intergration_test文件上运行呢?

use demo;

mod common;

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

针对binary crate的集成测试

如果项目是 binary crate,只含有src/main.rs没有src/lib.rs:

不能在tests 目录下创建集成测试

无法把main.rs的函数导入作用域

只有library crate 才能暴露函数给其它crate 用

binary crate意味着独立运行

 

你好:我的2025