Search code examples
rustintegration-testingrust-cargo

Cargo `OUT_DIR` env var not found when run a specific test


Can someone help me to understand this?

I have a rust project that has a lib crate: my_crate_2. Here is the file structure of it:

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


In my_crate_2/tests/my_crate_2.rs are my integration tests.

In the integration tests, I want to extract the env var OUT_DIR in them. According to the cargo doc, OUT_DIR should be set by Cargo.

A trivial test:

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

    #[test]
    fn test_add() {
        // I need to use env var `OUT_DIR` here
        // err: called `Result::unwrap()` on an `Err` value: NotPresent
        // note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
        let out_dir = std::env::var("OUT_DIR").unwrap();
        println!("OUT_DIR is {}", out_dir);

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

I ran all the integration tests with cargo test -- --nocapture in the my_crate_2/ dir, and the test passed (OUT_DIR existed).

cargo test -- --nocapture
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (target/debug/deps/my_crate_2-e7e58afb09a93b31)

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running tests/my_crate_2.rs (target/debug/deps/my_crate_2-9892d21b51d30121)

running 1 test
OUT_DIR is /workspaces/workspace/my_crate_2/target/debug/build/my_crate_2-443e542c04636da9/out
test tests::test_add ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests my_crate_2

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

But if I only run a specific test: cargo test --package my_crate_2 --test my_crate_2 -- tests::test_add --nocapture, the test would fail with OUT_DIR env var not found.

cargo test --package my_crate_2 --test my_crate_2 -- tests::test_add --nocapture
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running tests/my_crate_2.rs (target/debug/deps/my_crate_2-9892d21b51d30121)

running 1 test
thread 'tests::test_add' panicked at tests/my_crate_2.rs:10:48:
called `Result::unwrap()` on an `Err` value: NotPresent
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test tests::test_add ... FAILED

Can anyone help me to understand why OUT_DIR is not set by Cargo when targeting a single test? And how should I fix it?

I created a sandbox here. You can try it out. Thank you!


Solution

  • This issue is reported to Cargo on GitHub. Now it should be fixed. https://github.com/rust-lang/cargo/issues/13127#event-11421120844