You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行单个Rust集成测试时Cargo OUT_DIR环境变量缺失求助

问题:单独运行Rust集成测试时无法获取OUT_DIR环境变量

项目结构

my_project/
├── Cargo.toml
└── src/
    └── main.rs
my_crate_2/
├── Cargo.toml
|-- build.rs
└── src/
    └── lib.rs
|__ tests/ 
    |__my_crate_2.rs

测试代码与现象

在my_crate_2/tests/my_crate_2.rs的集成测试中尝试读取OUT_DIR:

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

    #[test]
    fn test_add() {
        // 错误:called `Result::unwrap()` on an `Err` value: NotPresent
        let out_dir = std::env::var("OUT_DIR").unwrap();
        println!("OUT_DIR is {}", out_dir);

        assert_eq!(add(2, 5), 7);
    }
}

现象:

  • 在my_crate_2/目录下执行cargo test -- --nocapture时,测试通过,OUT_DIR存在;
  • 执行cargo test --package my_crate_2 --test my_crate_2 -- tests::test_add --nocapture单独运行该测试时,测试失败,提示OUT_DIR不存在。

原因分析

OUT_DIR是Cargo在构建阶段(运行build.rs、编译库/测试二进制等环节)设置的环境变量,仅用于构建流程(比如让build.rs将生成的文件输出到指定目录),并非测试运行时的标准环境变量。

当运行完整的cargo test命令时,Cargo会触发完整构建流程,此时OUT_DIR存在于Cargo的进程环境中,测试进程启动时会继承这个变量,因此能读取到。但单独运行单个测试时:

  1. 如果测试二进制已编译完成且无变化,Cargo会直接启动已有二进制,此时测试进程的环境是当前shell环境,没有Cargo构建时的OUT_DIR;
  2. 即使触发重新构建,Cargo也不会主动将OUT_DIR传递给测试运行时的进程。

简言之:依赖OUT_DIR在测试运行时读取本身不符合设计意图,完整测试命令下能读取到只是巧合。

解决方案

最可靠的方式是通过cargo:rustc-env指令,将OUT_DIR嵌入到库的编译代码中,避免依赖运行时环境变量。

步骤1:修改build.rs传递OUT_DIR给编译器

fn main() {
    let out_dir = std::env::var("OUT_DIR").unwrap();
    // 告诉Rust编译器将LIB_OUT_DIR作为编译时环境变量嵌入到库中
    println!("cargo:rustc-env=LIB_OUT_DIR={}", out_dir);

    // 你的其他build.rs逻辑...
}

步骤2:在lib.rs中定义常量捕获该值

// 编译时从环境变量中读取OUT_DIR,嵌入为常量
pub const LIB_OUT_DIR: &str = env!("LIB_OUT_DIR");

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

步骤3:测试代码直接使用常量

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

    #[test]
    fn test_add() {
        // 直接使用预定义的常量,无需读取环境变量
        let out_dir = LIB_OUT_DIR;
        println!("OUT_DIR is {}", out_dir);

        assert_eq!(add(2, 5), 7);
    }
}

这样无论运行完整测试还是单独测试,都能正确获取OUT_DIR的值,因为它已经被编译到库代码中,与运行时环境无关。

内容的提问来源于stack exchange,提问作者shushi_piggy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:50:38