I have a number of tests defined inside some of my modules with:
#[cfg(test)]
mod tests {
...
and a number of tests found inside my /tests directory. All of these happen to need a common function called get_local() that I have put inside a utils module
+src
|-lib.rs
|-utils.rs
|-...
+tests
|_common.rs
Now since this function is only used in case I run tests I thought I should add a #[cfg(test)] above it.
#[cfg(test)]
pub fn get_local() -> SomeResult { ... }
and then I make sure it is inside lib.rs:
pub mod utils;
When I try using the function in tests/common.rs though:
use my_crate::utils::get_local;
and run the tests with the test command I get the error: no get_local in utils. This error only goes away if I remove #[cfg(test)] from the declaration of get_local. Why does this happen?
Why does this happen?
#[cfg(test)] is only active when the crate is being compiled into a test binary (instead of a library or normal binary) — the same condition under which #[test] functions are compiled to be run rather than ignored. But for a tests/ test, the crate being compiled in test mode is not your library — it's a separate binary crate for the test, which Cargo sets up to depend on your library compiled normally.
Thus, tests/ tests may only test the "public API" of your library — they see it no differently than a dependent crate outside your library.
As a workaround, you can use #[doc(hidden)] instead of #cfg(test)] so that the function is always available but undocumented, or you can put it in a module which is compiled into the test as well as the main library (but it's tricky to write code that works in both cases).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With