Rust 学习笔记:组织测试

Rust 学习笔记:组织测试

Rust 社区将测试分为两大类:单元测试和集成测试。

单元测试较小且更集中,每次只测试一个模块,并且可以测试私有接口。

集成测试完全在库之外,并且以与其他外部代码相同的方式使用代码,仅使用公共接口,并且每个测试可能使用多个模块。

单元测试

单元测试的目的是将每个代码单元与其他代码隔离开来,以快速查明代码在哪里工作,哪里没有按预期工作。

单元测试位于每个文件的 src 目录中,其中包含要测试的代码。惯例是在每个文件中创建一个名为 tests 的模块来包含测试函数,并用 #[cfg(test)] 注释模块。

测试模块和 #[cfg(test)] 注释

回想一下,当我们在本文的第一节中生成新的 adder 项目时,Cargo 为我们生成了以下代码:

pub fn add(left: u64, right: u64) -> u64 {
    left + right
}

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

    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }
}

属性 cfg 代表配置,并告诉 Rust 只有在给定某个配置选项时才应该包含以下项。在本例中,配置选项是 test,它由 Rust 提供,用于编译和运行测试。

#[cfg(test)] 注释告诉 Rust 只在运行 cargo test 时编译和运行测试代码,而不是在运行 cargo build 时。除了带有 #[test] 注释的函数外,这还包括可能在该模块中的任何辅助函数。这样可以在构建库时节省编译时间,并节省编译结果中的空间,因为不包括测试。

测试私有函数

Rust 的隐私规则都允许测试私有函数。测试只是 Rust 代码,而测试模块只是另一个模块。

示例:

pub fn add_two(a: usize) -> usize {
    internal_adder(a, 2)
}

fn internal_adder(left: usize, right: usize) -> usize {
    left + right
}

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

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

注意,internal_adder 函数没有被标记为 pub。因为我们使用 use super::*; 将所有测试模块的父模块的项带入作用域,然后测试可以调用 internal_adder 函数。

集成测试

集成测试完全在库之外,它们以与其他代码相同的方式使用库,这意味着它们只能调用库公共 API 的一部分函数。

集成测试的目的是测试库的许多部分是否可以正确地协同工作。独立工作的代码单元在集成时可能会出现问题,因此集成代码的测试覆盖率也很重要。

要创建集成测试,首先需要一个测试目录。

测试目录

在项目目录 src 旁边创建一个 tests 目录。Cargo 知道在这个目录中查找集成测试文件。然后,我们可以创建任意多的测试文件,Cargo 将把每个文件编译为一个单独的 crate。

再创建一个名为 tests/integration_test.rs 的新文件。当前目录结构应该是这样的:

adder
├── Cargo.lock
├── Cargo.toml
├── src
│   └── lib.rs
└── tests
    └── integration_test.rs

在 tests/integration_test.rs 中编写测试代码:

use adder::add_two;

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

Cargo 对 tests 目录进行特殊处理,不需要 #[cfg(test)] 注释,仅在运行 Cargo test 时才编译该目录中的文件。

运行 cargo test:

在这里插入图片描述

输出的三个部分包括单元测试、集成测试和文档测试。

请注意,如果某个部分中的任何测试失败,则不会运行后续的部分。
例如,如果单元测试失败,则不会有集成和文档测试的任何输出,因为只有在所有单元测试都通过时才会运行这些测试。

单元测试的第一部分与我们看到的相同:一行用于每个单元测试,然后是单元测试的总结行。

集成测试部分以 Running tests\integration_test.rs 行开头。接下来,在 Doc-tests addder 部分开始之前,有一行用于集成测试中的每个测试功能,还有一行用于集成测试结果的总结行。

每个集成测试文件都有自己的部分,所以如果我们在 tests 目录中添加更多的文件,就会有更多的集成测试部分。

要运行特定集成测试文件中的所有测试,请使用 cargo test 的 --test 参数,后跟文件名:

cargo test --test integration_test

该命令只运行 tests/integration_test.rs 中的所有测试。

集成测试中的子模块

如前所述,tests 目录中的每个文件都被编译为单独的 crate。当有一组辅助函数要在多个集成测试文件中使用时,可以将它们提取到一个公共模块中。

例如,如果我们创建 tests/common.rs 并在其中放置一个名为 setup 的函数,该函数可以在多个测试文件中的多个测试函数中调用。

在这里插入图片描述

再次运行测试,我们将在测试输出中看到一个针对 common 的新部分。尽管这个文件不包含任何测试函数,我们也没有从任何地方调用 setup 函数。

在这里插入图片描述

在测试结果中显示 common 并显示运行 0 个测试并不是我们想要的,我们只是想与其他集成测试文件共享一些代码。

为了避免在测试输出中出现 common,我们更改为创建 tests/common/mod.rs。项目目录现在看起来像这样:

├── Cargo.lock
├── Cargo.toml
├── src
│   └── lib.rs
└── tests
    ├── common
    │   └── mod.rs
    └── integration_test.rs

这是 Rust 也理解的旧的命名约定,以这种方式命名文件告诉 Rust 不要将 common 模块视为集成测试文件。我们将 setup 函数代码移动到 tests/common/mod.rs。

测试目录的子目录中的文件不会作为单独的 crate 编译,也不会在测试输出中包含部分。

我们可以在任何集成测试文件中使用 common 模块。下面是一个从 tests/integration_test.rs 中的 it_adds_two 测试中调用 setup 函数的例子:

use adder::add_two;

mod common;

#[test]
fn it_adds_two() {
    common::setup();

    let result = add_two(2);
    assert_eq!(result, 4);
}

二进制 crate 的集成测试

如果我们的项目是一个只包含 src/main.rs 文件而没有 src/lib.rs 文件的二进制 crate,我们就不能在 tests 目录中创建集成测试,也不能使用 use 语句将 src/main.rs 文件中定义的函数引入作用域。

只有库 crate可以暴露函数给其他 crate 使用。二进制 crate 必须独立运行。

这就是提供二进制文件的 Rust 项目有一个直接的 src/main.rs 文件的原因之一,该文件调用 src/lib.rs 文件中的逻辑。使用这种结构,集成测试可以测试库 crate,如果库 crate 提供的功能可以工作,那么 src/main.rs 文件中的少量代码也可以工作,并且这少量代码不需要测试。

内容概要:本文详细介绍了PMSM(永磁同步电机)的仿真研究及其两种关键控制方法:三电平SVPWM矢量控制和双环矢量控制。首先阐述了PMSM在现代电机驱动系统中的重要地位及其广泛的应用领域,如电动汽车、机器人和风力发电等。接着讨论了PMSM仿真的重要性,包括电气特性、机械特性和热特性等方面的考量。然后深入探讨了三电平SVPWM矢量控制技术的工作原理及其对电机性能的提升效果,如提高运行效率和减少谐波失真。随后介绍了PMSM双环矢量控制的具体实现方式,即内环电流控制和外环速度控制相结合的方法,强调了这种方法在提高电机动态性能和稳定性方面的优势。最后对比了传统三电平控制方法和双环矢量控制方法的特点,指出了各自的优势和应用场景。 适合人群:从事电机控制系统研究的技术人员、高校相关专业师生、对电机控制感兴趣的工程技术人员。 使用场景及目标:适用于需要深入了解PMSM控制技术和仿真实现的研究项目和技术开发。目标是帮助读者掌握PMSM的仿真建模方法,理解并应用三电平SVPWM和双环矢量控制技术,以优化电机性能。 其他说明:本文不仅提供了理论分析,还通过MATLAB进行了详细的仿真演示,使读者能够直观地看到不同控制方法的效果。这对于实际工程项目的设计和优化具有重要的指导意义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值