I have a file with some benchmarks and tests and would like to test against stable, beta and nightly. However, either I don\'t use the benchmark or stable/beta complain. Is ther
Cargo supports a benches directory for benchmark tests. If you put them in there, you can just never run "cargo bench" on beta/stable, and only run it on nightly.
In my projects, I place benchmarks in a separate module, just like I do for tests. I then create a Cargo feature that enables them. In this excerpt, I used the feature name unstable
, but you can use anything you'd like:
Cargo.toml
# ...
[features]
unstable = []
# ...
src/lib.rs
#![cfg_attr(feature = "unstable", feature(test))]
#[cfg(test)]
mod tests {
#[test]
fn a_test() {
assert_eq!(1, 1);
}
}
#[cfg(all(feature = "unstable", test))]
mod bench {
extern crate test;
use self::test::Bencher;
#[bench]
fn a_bench(b: &mut Bencher) {
let z = b.iter(|| {
test::black_box(|| {
1 + 1
})
});
}
}
The line #[cfg(all(feature = "unstable", test))]
says to only compile the following item if the feature is set and we are compiling in test mode anyway. Likewise, #![cfg_attr(feature = "unstable", feature(test))]
only enables the test
feature flag when the unstable
feature is enabled.
Here's an example in the wild.
Is there a way to hide all the benchmark parts when using stable/beta?
Yes, and you can do it automatically using a build script, so it is not necessary to specify --features
when executing cargo. In the build script you can detect the version of the Rust compiler and define a feature ("nightly"
for example). Then, in the source code you can group your benchmarks and enable them if the feature was defined.
Cargo.toml
[package]
build = "build.rs"
[features]
nightly = []
[build-dependencies]
rustc_version = "0.1.*"
build.rs
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
fn main() {
if version_meta().channel == Channel::Nightly {
println!("cargo:rustc-cfg=feature=\"nightly\"");
}
}
src/lib.rs
#![cfg_attr(all(feature = "nightly", test), feature(test))]
#[cfg(all(feature = "nightly", test))]
extern crate test;
pub fn add_two(a: i32) -> i32 {
a + 2
}
#[cfg(test)]
mod tests {
// tests
}
#[cfg(all(feature = "nightly", test))]
mod benchs {
use test::Bencher;
// benchs
}