Skip to content

Guide new users to add use super::*; to mod test. #10559

@sunfishcode

Description

@sunfishcode

Problem

cargo init --lib produces a src/lib.rs file contaning this:

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

When I was first learning Rust, I'd start with this code, and add a new function, and a unit test, like this:

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

#[cfg(test)]
mod tests {
    #[test] 
    fn it_works() {
        let result = add_numbers(2, 2);
        assert_eq!(result, 4);
    }
}

But, this doesn't compile:

error[E0425]: cannot find function `add_numbers` in this scope
 --> src/lib.rs:9:22
  |
9 |         let result = add_numbers(2, 2);
  |                      ^^^^^^^^^^^ not found in this scope
  |
help: consider importing this function
  |
8 |     use crate::add_numbers;
  |

So first, this in itself is a mild papercut—the seemingly obvious thing didn't work. But next, if I would follow rustc's suggestions, or let IDEs fix this for me, I'd eventually end up with a big pile of uses, as I write more code and add tests for it. This would add more papercuts: clutter, and a focal point for merge conflicts.

It would almost always be better for me to use use super::* inside the mod tests, because once that's added, it avoids these papercuts from then on. So the feature request is: can we do more to guide users to use super::*;?

The relevant documentation does recommend using use super::*;, but when I was learning Rust, I didn't read that section because I knew what an "assert" was from other languages and didn't think I needed to read that whole section in the docs, so I missed the use super::*; advice within.

As a historical note, these papercuts contributed to my forming a habit of writing unit tests without mod tests, which is what prompted the discussion which led to #10531.

Proposed Solution

Adding use super::*; to the current code would get an unused-import warning. So one option would be to add it, but commented out, like this:

#[cfg(test)]
mod tests {
    // Uncomment this to use items from the containing module.
    //use super::*;

    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

Notes

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`Command-initCommand-new

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions