Rust 测试:单元测试、集成测试、端到端测试——完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 Rust 中的测试简单又可靠

Rust 从设计之初就是一门帮助编写安全可靠代码的语言。然而,即使是最严格的类型系统也无法保证业务逻辑的正确性。这正是测试发挥作用的地方。在 Rust 中,编写测试的过程直接内置于 cargo 工具链中,使其变得异常便捷和易用。

在本文中,我们将探讨三个测试层级:unit(单元测试)、integration(集成测试)和 e2e(端到端测试)。你将学习如何编写测试、何时使用哪种方法以及如何自动化代码验证。本文内容对新手和转向 Rust 的有经验开发者都很有帮助。

Unit 测试:从内部进行测试

Unit 测试(单元测试)是最基本且最常用的测试类型。它们独立于系统其余部分,对单个函数、方法或模块进行测试。在 Rust 中,通常将 unit 测试直接写在与被测代码相同的文件中,或者写在模块内单独的 tests.rs 文件中。

如何在 Rust 中编写 unit 测试

创建测试使用 #[test] 属性。测试放在带有 #[cfg(test)] 属性的模块中,该属性确保测试代码不会进入最终构建。

// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

pub fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("Division by zero"))
    } else {
        Ok(a / b)
    }
}

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

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }

    #[test]
    fn test_add_negative() {
        assert_eq!(add(-1, 1), 0);
    }

    #[test]
    fn test_divide_success() {
        let result = divide(10.0, 2.0);
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), 5.0);
    }

    #[test]
    fn test_divide_by_zero() {
        let result = divide(10.0, 0.0);
        assert!(result.is_err());
        assert_eq!(result.unwrap_err(), "Division by zero");
    }
}

运行 unit 测试

使用一条命令即可运行测试:

cargo test

输出将显示有多少测试通过,多少测试失败。要运行特定测试,请使用过滤器:

cargo test test_add

Unit 测试非常适合检查边界情况、错误处理和算法的正确性。它们速度快且不需要外部依赖。

Integration 测试:检查模块间的交互

集成测试检查库或应用程序的不同模块如何协同工作。与 unit 测试不同,它们无法访问内部函数(除非这些函数被导出为 pub)。集成测试写在项目根目录下单独的 tests/ 文件夹中。

集成测试的结构

在项目根目录创建 tests/ 文件夹,并在其中添加测试文件。每个文件都将作为独立的 crate 进行编译。

// tests/integration_test.rs
use my_crate; // 你的 crate 名称

#[test]
fn test_add_integration() {
    assert_eq!(my_crate::add(10, 20), 30);
}

#[test]
fn test_divide_integration() {
    let result = my_crate::divide(100.0, 4.0);
    assert_eq!(result.unwrap(), 25.0);
}

测试的公共模块

如果多个集成测试使用相同的辅助函数,请将它们提取到公共模块中。为此,创建文件夹 tests/common/mod.rs:

// tests/common/mod.rs
pub fn setup() {
    // 初始化日志记录器、数据库等
    println!("Setting up test environment...");
}

// tests/another_test.rs
mod common;

#[test]
fn test                

博客

书籍推荐