Rust目录测试宏库dir-test-macros的使用,自动化目录结构测试与宏生成工具

以下是关于Rust目录测试宏库dir-test-macros的使用介绍:

Rust目录测试宏库dir-test-macros的使用

元数据

  • 版本: 0.4.1
  • 发布时间: 8个月前
  • 2021 edition
  • 许可证: Apache-2.0
  • 大小: 7.18 KiB

安装

在项目目录中运行以下Cargo命令:

cargo add dir-test-macros

或在Cargo.toml中添加以下行:

dir-test-macros = "0.4.1"

示例代码

// 首先添加依赖到Cargo.toml
// dir-test-macros = "0.4.1"

use dir_test_macros::dir_test;

// 使用dir_test宏自动生成测试
#[dir_test(
    dir: "$CARGO_MANIFEST_DIR/examples",  // 测试目录
    glob: "*.rs",                         // 文件匹配模式
)]
fn test_examples(path: &str) {
    // 这里可以编写测试逻辑
    // 宏会自动为每个匹配的文件生成一个测试用例
    println!("Testing file: {}", path);
    
    // 示例: 读取文件内容
    let content = std::fs::read_to_string(path).unwrap();
    assert!(!content.is_empty());
}

// 也可以配置更多选项
#[dir_test(
    dir: "$CARGO_MANIFEST_DIR/tests",
    glob: "**/*.txt",
    ignore: "skip_me.txt",  // 忽略特定文件
)]
fn test_text_files(path: &str) {
    // 测试逻辑
    println!("Testing text file: {}", path);
}

主要功能

  1. 自动扫描指定目录的文件
  2. 根据glob模式匹配文件
  3. 为每个匹配的文件自动生成测试用例
  4. 支持忽略特定文件
  5. 使用$CARGO_MANIFEST_DIR等环境变量

典型使用场景

  • 测试目录中的所有示例文件
  • 验证文档文件的结构
  • 批量测试配置文件
  • 自动化文件内容检查

注意: 使用前请确保在Cargo.toml中添加了正确的依赖。

完整示例

// 测试配置文件有效性
#[dir_test(
    dir: "configs",
    glob: "*.yaml",
    ignore: "template.yaml"
)]
fn test_config_files(path: &str) {
    use serde_yaml::Value;
    
    let file = std::fs::File::open(path).unwrap();
    let config: Value = serde_yaml::from_reader(file).unwrap();
    
    assert!(config.is_mapping());
    assert!(config["name"].is_string());
}

// 测试文档文件结构
#[dir_test(
    dir: "docs",
    glob: "*.md",
)]
fn test_markdown_files(path: &str) {
    let content = std::fs::read_to_string(path).unwrap();
    
    // 确保每个Markdown文件都有标题
    assert!(content.starts_with("# "));
    
    // 确保文件长度合理
    assert!(content.len() > 100);
}

1 回复

Rust目录测试宏库dir-test-macros使用指南

dir-test-macros是一个用于自动化目录结构测试和宏生成的Rust库,它可以帮助开发者验证项目目录结构是否符合预期,并生成相应的测试代码。

功能特点

  1. 自动化目录结构验证
  2. 宏生成测试代码
  3. 支持文件内容匹配
  4. 可配置的测试条件

安装方法

Cargo.toml中添加依赖:

[dependencies]
dir-test-macros = "0.1"

基本使用方法

1. 简单目录结构测试

use dir_test_macros::dir_test;

#[dir_test(
    dir: "$CARGO_MANIFEST_DIR/examples",
    glob: "*.rs"
)]
fn test_examples(_content: &str, _name: &str) {
    // 这个测试会对examples目录下所有.rs文件运行
}

2. 带过滤条件的测试

#[dir_test(
    dir: "src",
    glob: "*.rs",
    filter: "is_file"
)]
fn test_src_files(content: &str, name: &str) {
    assert!(!content.is_empty(), "文件{}内容为空", name);
}

3. 文件内容匹配测试

#[dir_test(
    dir: "tests",
    glob: "*.rs",
    pattern: r"fn test_.*\("
)]
fn test_files_have_test_functions(_matched: &str, name: &str) {
    // 确保所有测试文件都包含以"test_"开头的函数
}

高级用法

1. 自定义匹配器

#[dir_test(
    dir: "src",
    glob: "**/*.rs",
    pattern: r"struct \w+",
    mapper: |m| format!("Found struct: {}", &m[0])
)]
fn test_struct_declarations(found: String, name: &str) {
    println!("在文件{}中发现: {}", name, found);
}

2. 组合多个条件

#[dir_test(
    dir: ".",
    glob: "*.toml",
    filter: r#"|p| p.file_name().unwrap() == "Cargo.toml""#,
    pattern: r"version = .*\d+\.\d+\.\d+"
)]
fn test_cargo_version(_m: &str, _name: &str) {
    // 验证Cargo.toml中的版本号格式
}

配置选项

参数 说明
dir 要测试的目录路径,支持环境变量如$CARGO_MANIFEST_DIR
glob 文件匹配模式,如*.rs**/*.toml
filter 过滤函数或表达式,用于进一步筛选文件
pattern 正则表达式,用于匹配文件内容
mapper 对匹配结果进行处理的闭包
ignore 忽略某些文件或目录的模式

实际应用示例

// 测试文档中的代码示例是否能够编译
#[dir_test(
    dir: "docs/examples",
    glob: "*.rs",
    pattern: r"fn main\(\) \{[^}]*\}"
)]
fn test_doc_examples(content: &str, name: &str) {
    let result = std::panic::catch_unwind(|| {
        let _ = rustc_test::compile_test(content);
    });
    assert!(result.is_ok(), "文档示例{}无法编译", name);
}

注意事项

  1. 宏展开会在编译时进行,因此错误的配置会导致编译错误
  2. 对于大型目录结构,测试可能会增加编译时间
  3. 正则表达式使用Rust的regex crate语法
  4. 路径相关操作使用std::path::Path的功能

这个库特别适合需要严格目录结构的项目,或者需要确保特定文件内容模式的场景,如文档项目、代码生成项目等。

完整示例代码

// 导入宏库
use dir_test_macros::dir_test;

// 测试项目中的所有Rust文件是否有正确的版权声明
#[dir_test(
    dir: "$CARGO_MANIFEST_DIR/src",
    glob: "**/*.rs",
    pattern: r"// Copyright \d{4} .*"
)]
fn test_copyright_headers(matched: &str, name: &str) {
    assert!(
        matched.contains("Copyright"),
        "文件{}缺少正确的版权声明: {}",
        name,
        matched
    );
}

// 测试所有测试文件是否包含#[test]属性
#[dir_test(
    dir: "tests",
    glob: "*.rs",
    filter: r#"|p| p.to_str().unwrap().contains("test_")"#,
    pattern: r"#\[test\]"
)]
fn test_files_have_test_attributes(_matched: &str, name: &str) {
    println!("测试文件{}包含#[test]属性", name);
}

// 验证配置文件的格式
#[dir_test(
    dir: "config",
    glob: "*.toml",
    pattern: r"^\[.+\]$",
    mapper: |m| m.to_string()
)]
fn test_toml_sections(section: String, name: &str) {
    assert!(
        section.starts_with('[') && section.ends_with(']'),
        "配置文件{}中的节格式不正确: {}",
        name,
        section
    );
}

// 测试文档示例是否有正确的标记
#[dir_test(
    dir: "examples",
    glob: "*.rs",
    pattern: r"//! \[Example\]: .*",
    ignore: "old_*.rs"
)]
fn test_doc_example_markers(marker: &str, name: &str) {
    assert!(
        marker.contains("Example"),
        "示例文件{}缺少正确的文档标记: {}",
        name,
        marker
    );
}
回到顶部