Unit Testing Public Scopes Only

The Rust Book states that unit tests can test both public and private items. Is there a way to toggle this behavior such that one can opt out of the ability to test private items? I would like a few unit tests to validate that a certain feature is/isn't publicly accessible.

One alternative approach would be to stick such tests in the integration test directory, though I think this isn't ideal because such tests:

  1. May not represent a true intercomponent interaction.
  2. May not be run as often, due to integration test overhead.

Privacy rules are applied normally for tests, in that testing private items must be done from a scope that is normally allowed to see them. So, if you have a separate public_tests module that is outside the privacy barrier, you'll be testing the public interface. For example:

mod lib {
    // Put all of your implementation code here
    pub struct S {
        i: u32,
    }

    impl S {
        pub fn new() -> S {
            S { i: 42 }
        }
    }
}

pub use lib::*;

#[cfg(test)]
mod public_tests {
    use crate::*;
    #[test]
    fn make_s() {
        // Works fine
        S::new();
    }

    #[test]
    fn make_raw_s() {
        // Compile error
        S { i: 3 };
    }
}
3 Likes

Doctests also only test public API, but I find that they can have quite a linking overhead.

That same linking overhead is present in integration tests, but there it can at least be combatted by merging multiple integration test modules into one compilation unit. (example. That file even includes a check for files not mentioned, for the paranoid)

I'm not sure why this should bother you from a practicality standpoint. We use the term "integration tests" for the tests directory because that's broadly what it is designed for, but that shouldn't forbid other usages.

4 Likes

To clarify, I wasn't referring to the linking overhead, but the overhead of external system calls, such as talking to a server or a database.

I'm not sure why this should bother you from a practicality standpoint. We use the term "integration tests" for the tests directory because that's broadly what it is designed for, but that shouldn't forbid other usages.

Thank you - I was worried this was not idiomatic and, thus, would be frowned upon.

1 Like

I would say that this is precisely what tests/ is for: testing of the public API.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.