How do I create a test only module in a separate file

Hey folks,

Every dummy knows that you can add tests this way:

#[cfg(test)]
mod tests {
    use super::*;
    // and so on and so forth
}

I'd like to create a new module containing strings to use in tests like so:

const NO_RESULTS_JSON: &str = r#"
    {
        "total": 0,
        "hits" : [],
    }
    "#;

If that were in a module called test_json.rs how would I mark it so it is only included in the test build, as per the first example?

Thanks again!

Test modules function exactly like other modules. If you want to separate a module into a different file, the same rules apply. If you then want to conditionally exclude the module from non-test builds, that's what you use the #[cfg(test)] for.

So let's say you have a module src/foo.rs:

pub fn foo() {}

...

#[cfg(test)]
mod tests {
    const NO_RESULTS_JSON: &str = "";

    ...
}

you can then extract the tests module into its own file src/foo/tests.rs:

const NO_RESULTS_JSON: &str = "";

...

and keep the declaration in the foo module like this:

pub fn foo() {}

...

#[cfg(test)]
mod tests;
3 Likes

Oh sweet, thanks!

1 Like

Also, if you want to test the public functions, you can use the tests directory (next to the src dir): Test Organization - The Rust Programming Language

Thanks for the suggestion. My project is currently binary only, it needs to be a library for that, right?

I did read that a project can be both, but haven't gone down that path yet.

Probably not the best idea, but you can run the binary directly using std::process::Command , if you are still interested in integration tests. The cleanest solution would probably be having a lib.rs.

1 Like

Just add a lib.rs file, and declare there the modules you want to test in integration AND all the modules declared in main (so that their tests are executed):

  • cargo run will run the main.rs binary.
  • cargo test will run all tests EXCEPT the one in main.rs (it runs the inline tests as if it was a library, so it starts at lib.rs to find the modules to test).
1 Like

Do I need to edit Cargo.toml as per this?

No, because you don't want to make a lib. the lib.rs file is only there for the integration tests.

1 Like