Can I make an object public for integration tests and/or benchmarks only?

前端 未结 2 968
说谎
说谎 2020-12-12 00:47

As suggested by The Book, I have moved the integration tests in my crate to a tests directory. Some of those tests use functions that I don\'t want to export ou

相关标签:
2条回答
  • 2020-12-12 01:20

    One difference between integration tests and unit tests is that integration tests is supposed to test the "public API" of your crate only. Tests for internal functions is fine to keep together with the functions themselves in the src tree.

    If you want to keep them a little separate, you can use a test submodule to the module containing the functions to test, as private parts are available to submodules.

    If you still really want to have internal / unit tests in the tests in the tests directory, you can use a feature flag to enable public wrappers of internal functions to test (and mark the tests with the same feature flag). Something like this in the code:

    #[cfg(feature = "testable_privates")]
    pub fn exposed_something(args) {
        something_private(args)
    }
    

    Then in your test methods, you can import and call exposed_something. If the feature testable_privates is not defined, your tests will fail to compile. To solve that, use the feature flag to make the tests conditional as well;

    #[cfg(feature = "testable_privates")]
    #[test]
    fn test_something() {
        assert_eq!(exposed_something(my_args), expected_result)
    }
    

    Also, before doing that you need to define the feature in your Cargo.toml, like so:

    [features]
    testable_privates = []
    

    (The empty array is to signify that the feature does not require any otherwise optional dependencies).

    Now, if you just run cargo test, both exposed_something and test_something will just be silently ignored, but if you run cargo test --features testable_privates, they will be compiled and tested.

    As you see, this gets rather complicated, so I really think it is a better idea to just test public aspects of your crates from tests and keep tests of private methods close to those methods themselves in src.

    0 讨论(0)
  • 2020-12-12 01:20

    You can probably do it by adding a public module that only exists when testing and that re-exports the required symbols. Something like:

    #[cfg(test)]
    pub mod testing_parser {
        pub use parser::foo;
    }
    

    Then use my_crate::testing_parser::foo in your tests.

    0 讨论(0)
提交回复
热议问题