cargo test incorrectly warns for dead code
Hi!
I got unexpected dead code warnings when executing cargo test with multiple test files. I use a very simple example below that reproduces the issue.
I have two files that contains tests, tests/test_one.rs and tests/test_two.rs. Both contains exactly the same content (except for the unique test function name they contain):
mod routines;
#[test]
fn test_one() {
routines::my_routine();
}
And another file called tests/routines.rs that simply contains:
pub fn my_routine() {
}
When I execute cargo test, the two tests are executed successfully and there is no raised warning. But if I remove the my_routine() call from one of the two tests, cargo test stills end up successfully but raises a warning on pub fn routine() saying function is never used. However, one test still calls the function, so there is no dead code as stated.
I got the same issue with both rust stable (1.22.1) and rust nightly (1.24.0).
Thanks.
This is not actually a bug, as far as I know!
And another file called tests/routines.rs that simply contains:
Cargo is also attempting to compile this file as its own test. See the explanation here: https://doc.rust-lang.org/book/second-edition/ch11-03-test-organization.html#submodules-in-integration-tests
I believe if you move this file to
tests/routines/mod.rs, this will work without warning.Steve Klabnik at 2017-11-29 20:00:06
Yes, when replacing
tests/routines.rsbytests/routines/mod.rs, Cargo does not attempt to compileroutines.rsas a test.But, the warning is still raised at the first execution of
cargo test(and only at the first execution).Here the details of what I do after changing
tests/routines.rstotests/routines/mod.rs:- execute
cargo testmultiple times with two calls tomy_routine()(one in each test) -> no warning - remove one call to
my_routine()from one of the two tests - execute
cargo test-> one warningfunction is never usedis raised formy_routine() - execute
cargo testagain (without code modification) -> no warning anymore
For exactly the same code,
cargo testoutputs a warning only during the first execution. Furthermore, for each execution, the two tests are run somy_routine()is called. Maybe I just miss something, but this is kind of weird, isn't it ?Jean LELIEVRE at 2017-11-29 21:07:33
- execute
I believe cargo compiles each "integration test" (i.e. file in
tests/*.rs) independently. So if the helper in a common moduletests/routines/mod.rsis used intests/test_one.rs, but not intests/test_two.rs, there will be a warning when compilingtest_two.rs.(
cargo testre-builds only what needs to be rebuilt, that's why it only warns on the first execution.)I've worked around this by using
mod routines; pub use routines::*;intests/*.rs.Nickolay at 2019-04-28 22:35:23
So we're running into the same issue and I think the workaround
mod routines; pub use routines::*;is not optimal as that does hide truly dead code. I think this is a legitimate cargo bug.Sven-Hendrik Haase at 2019-04-29 11:28:39
This is either a bug or a design flaw.
In TypeScript, an exported item (even if it is never used) is never considered dead code. I don't why it is in Rust.
Khải at 2019-04-29 11:43:46
@KSXGitHub well, if you export the items from the crate with
mod routines; pub use routines::*;it's not considered dead code.What @svenstaro is asking for would require considering all targets/configurations before determining if an item is dead code instead of letting the rust compiler report them when compiling an individual crate...
Nickolay at 2019-04-29 12:16:50
I am noticing this issue,
when will the PR above be released in rust ? ^
Josh Weinstein at 2019-05-03 22:45:13
We are encountering the same issue. I am not sure I am comfortable with no dead code warnings. Perhaps an alternative approach to organizing code people would suggest if there is no re-design any time soon?
eftychis at 2019-08-29 21:45:46
If the module is implemented in
tests/routines/mod.rs, just usingpub mod routines;, in every test file that I wish to useroutinesmodule, solved the problem for me. This works as expected, imo, because:- It allows to declare a shared module for different tests
- Does not report unused code warning if you don't use all the functions from the shared module, which is good, imo
- Does not report unused code warning in the test file that does not use
routinesat all.
So, it looks to me that exported stuff is also not considered a dead code in rust, but it needs to be declared/imported with
pub. There is a nice example of the similar use-case in the rust book: https://doc.rust-lang.org/1.29.2/book/2018-edition/ch07-02-controlling-visibility-with-pub.html.Petar Radovic at 2019-11-01 13:28:32
We are still encountering this issue with the last version of Rust (1.45.0 nightly)
Yohann Bacha at 2020-05-27 10:54:36
Allowing dead code warnings, and running "cargo test", seems to show truly dead code warnings.
Earl Dukerschein at 2021-12-24 15:49:10
This is still a problem, with any test not using all helpers cargo reports the helpers as dead code.
Michal Srb at 2023-01-07 17:01:47
The rust book's 11.3. Test Organization encourages to create
tests/common/mod.rsfor test setup codes.However, this results to false positive in some cases such as
common::common_func1()is only used bytests/test1.rsandcommon::common_func2()is only used bytests/test2.rs.JungChul Shin at 2024-01-01 07:18:49
A workaround for this issue is to use the
tests/it/main.rspattern as described by https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html (although I usually spell ittests/integrations/main.rsin my own projects).Charles Hall at 2024-01-05 00:29:44
+1 to following the
tests/it/main.rspattern in https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html as a workaround for this issue.Clement Tsang at 2024-01-15 06:45:11