testingrustbenchmarkingsource-sets

How can one share the code between tests and benches in Rust?


I started writing benchmarks in Rust with "bench" and Rust nightly as written in the docs.

In order to share the code between test and benchmarks i've added Option<&mut Bencher> and either run the code block directly or with bencher passed ("src/lib.rs"):

fn block_requests(bencher_option: Option<&mut Bencher>, ...) {
    ...

    let mut block = || {
       ... // shared
    }

    match bencher_option {
            // regular test
            None => block(),

            // benchmark
            Some(bencher) => {
                bencher.iter(block);
            }
        }
    ...
}

// call from test
#[test]
fn test_smth() {
    block_requests(None, &requests, &mut matcher);
}


// call from benchmark
#[bench]
fn bench_smth(b: &mut Bencher) {
    block_requests(Some(b), &requests, &mut matcher);
}

Now i want to use Rust stable for benchmarks. Since "bencher" crate is not updated for 3 years it seems that "criterion" crate is the default option. For this i have to move the code to "./benches/my_benchmark.rs".

How can i still share the block_requests(..) between the tests and benchmarks?


Solution

  • tests/ and benches/ work the same way as src/main.rs or src/bin/*.rs: they are separate binary crates. This means that they must refer to items in your library crate by name, and those items must be visible.

    So, you need to change

    fn block_requests(bencher_option: Option<&mut Bencher>, ...) {
    

    to make it public, and you will probably also want to add #[doc(hidden)] so that your library documentation does not contain testing helpers:

    #[doc(hidden)]
    pub fn block_requests(bencher_option: Option<&mut Bencher>, ...) {
    

    Then, in your tests and benchmarks, use it by giving the name of your crate.

    use my_library_crate_name::block_requests;
    
    fn bench_smth(...) {...}
    

    (You cannot use use crate::block_requests here because the keyword crate refers to the benchmark binary crate, not the library crate.)