Sharing helper function between unit and integration tests


#1

In src/lib.rs I have

pub fn do_stuff(_: &str) -> i32 { 1 }

#[cfg(test)]
pub mod tests {

  use super::*;

  pub fn helper_function() -> String {
    "foo".to_string()
  }

  #[test]
  fn unit_test_1() {
    assert_eq!(do_stuff(&helper_function()), 1);
  }
}

and then I have an integration test in tests/integration_tests.rs:

extern crate sharing;

use sharing::tests::helper_function;

#[test]
fn integration_test1() {
  assert_eq!(helper_function(), "foo");
}

However the build fails with

error[E0432]: unresolved import `sharing::tests::helper_function`
 --> tests/integration_tests.rs:3:5
  |
3 | use sharing::tests::helper_function;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Could not find `tests` in `sharing`

if I comment out the #[cfg(test)] around the tests module, then everything works, but then my production build has a bunch of test code cluttering it up. Is there any easy way to have the same #[cfg(test)] helper function visible to both unit and integration tests?

thanks

Mark


#2

I hope there is a better way, but one possibility is to put the helper_function in a separate file and include!() that file from both the test mod in src/lib.rs and from your integration test file(s).

That way, you don’t have to actually have the helper_function copied in multiple source files, but it will still seem like you have to the compiler. So, not very good, but might be a way forward unless someone suggests something better.


#3

Another way to do the same thing is with #[path], like:

#[path="../src/helper.rs"]
mod helper;

Still not great, but slightly cleaner than include!() IMO.


#4

The issue here is that integration tests do not compile your crate with cfg(test); they’re compiled exactly as a user would use them.

I like the mod trick.