cargo test incorrectly warns for dead code

d6d1ac9
Opened by Jean LELIEVRE at 2024-01-15 06:45:17

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.

  1. 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

  2. Yes, when replacing tests/routines.rs by tests/routines/mod.rs, Cargo does not attempt to compile routines.rs as 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.rs to tests/routines/mod.rs:

    1. execute cargo test multiple times with two calls to my_routine() (one in each test) -> no warning
    2. remove one call to my_routine() from one of the two tests
    3. execute cargo test -> one warning function is never used is raised for my_routine()
    4. execute cargo test again (without code modification) -> no warning anymore

    For exactly the same code, cargo test outputs a warning only during the first execution. Furthermore, for each execution, the two tests are run so my_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

  3. I believe cargo compiles each "integration test" (i.e. file in tests/*.rs) independently. So if the helper in a common module tests/routines/mod.rs is used in tests/test_one.rs, but not in tests/test_two.rs, there will be a warning when compiling test_two.rs.

    (cargo test re-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::*; in tests/*.rs.

    Nickolay at 2019-04-28 22:35:23

  4. 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

  5. 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

  6. @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

  7. I am noticing this issue,

    when will the PR above be released in rust ? ^

    Josh Weinstein at 2019-05-03 22:45:13

  8. 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

  9. If the module is implemented in tests/routines/mod.rs, just using pub mod routines;, in every test file that I wish to use routines module, solved the problem for me. This works as expected, imo, because:

    1. It allows to declare a shared module for different tests
    2. Does not report unused code warning if you don't use all the functions from the shared module, which is good, imo
    3. Does not report unused code warning in the test file that does not use routines at 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

  10. 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

  11. Allowing dead code warnings, and running "cargo test", seems to show truly dead code warnings.

    Earl Dukerschein at 2021-12-24 15:49:10

  12. 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

  13. The rust book's 11.3. Test Organization encourages to create tests/common/mod.rs for test setup codes.

    However, this results to false positive in some cases such as common::common_func1() is only used by tests/test1.rs and common::common_func2() is only used by tests/test2.rs.

    JungChul Shin at 2024-01-01 07:18:49

  14. A workaround for this issue is to use the tests/it/main.rs pattern as described by https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html (although I usually spell it tests/integrations/main.rs in my own projects).

    Charles Hall at 2024-01-05 00:29:44

  15. +1 to following the tests/it/main.rs pattern 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