I have a code organization issue and would like to know how others usually deal with that. I'm trying to use proptest and creating a function to generate strategies for some type of mine:
fn strategy() -> impl Strategy<Value = Foo> { ... }
I can implement that function in two ways, either only using the public API of Foo or using private implementation detail. I prefer using the private API because it will generate much better values for property testing. Using the public API would really hurt the testability since it requires a oneof!
and covers only a small subset of the possible values without using other functions that are heavy etc. Basically I need to use the private API for the implementation of strategy()
.
But the tests I want to setup only use the public API of Foo so are better located in integration tests folder tests/
. Ideally what I'd like to have is something like the following:
// lib.rs
#[cfg(test)]
impl Foo {
pub fn strategy() -> impl Strategy<Value = Foo> { ... }
}
// tests/foo.rs
proptest! {
#[test]
fn test_foo(foo in Foo::strategy()) { ... }
}
But the issue is that the things under #[cfg(test)]
in the lib code do not seem to be available in integration tests. An easy solution would be to remove the cfg(test) but proptest is only in my tests dependencies and I'd like to avoid putting it in the normal dependencies. Otherwise I could put everything in unit tests, but they don't really belong there.
How would you deal with that?
Concretely, the Foo type above is Range
defined here in case that helps: https://github.com/mpizenberg/pubgrub-rs/blob/master/src/range.rs#L23 and I'd like to do property testing to verify that intersection, union and complement of sets verify few properties.