当不使用夜版时如何忽略基准测试?

11

我有一个带有一些基准测试的文件,想要针对稳定版、Beta版和Nightly版进行测试。但是,无论是我不使用基准测试还是使用稳定/ Beta版时出现问题。是否有一种方法可以在使用稳定版/ beta版时隐藏所有基准测试部分?

中以下代码为例:

#![feature(test)]

extern crate test;

pub fn add_two(a: i32) -> i32 {
    a + 2
}

#[cfg(test)]
mod tests {
    use super::*;
    use test::Bencher;

    #[test]
    fn it_works() {
        assert_eq!(4, add_two(2));
    }

    #[bench]
    fn bench_add_two(b: &mut Bencher) {
        b.iter(|| add_two(2));
    }
}

我正在使用rustup,希望同一个文件能够在所有构建中都能工作,类似这样的调用:

rustup run nightly cargo bench --bin bench --features "bench"
rustup run nightly cargo test --bin bench --features "bench"
rustup run beta cargo test --bin bench
rustup run stable cargo test --bin bench

我能够使用#![cfg_attr(feature = "bench", feature(test))]隐藏#![feature(test)]。 我能否对其余的基准测试部分采取类似的方法?有什么好的功能标志资源?


你尝试过将基准测试放入它们自己的文件中(在 bench 文件夹中)吗? - oli_obk
2
“benches”文件夹至少对于库似乎是有效的。我不确定如何与例如来自bin/bench.rs的函数一起使用它。我还发现在所有基准测试相关内容前面写入#[cfg(feature = "bench")]可以与--features "bench"标志一起使用。 - Dominik Müller
4个回答

19

在我的项目中,我会像测试一样将基准放在单独的模块中。然后我创建一个 Cargo 特性来启用它们。在这个片段中,我使用了特性名 unstable,但你可以使用任何你想要的名称:

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
            })
        });
    }
}

#[cfg(all(feature = "unstable", test))]这一行表示仅在设置了该特性并且我们正在测试模式下编译时才编译后面的项。同样,#![cfg_attr(feature = "unstable", feature(test))]只有当启用了unstable特性时才启用test特性标志。

这里有一个实际例子


9

Cargo支持一个用于基准测试的benches目录。如果你把基准测试放在那里,你就可以只在夜间运行cargo bench,而在beta/stable版本上永远不需要运行它。


问题的评论包括:*benches文件夹似乎至少对库有效。我不确定如何与bin/bench.rs中的函数一起使用* — 也许你能理解这是什么意思并解决它? - Shepmaster
通常基准测试是针对特定函数而不是二进制文件的。因此,我认为这是不可行的。 - Steve Klabnik

8

在使用稳定版/测试版时,有没有一种方法可以隐藏所有基准部分?

是的,您可以使用构建脚本自动执行此操作,因此在执行cargo时不需要指定--features。在构建脚本中,您可以检测Rust编译器的版本并定义一个特性(例如"nightly")。然后,在源代码中,您可以将基准分组并在定义了该特性时启用它们。

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
}

0
将您的基准测试放在“benches”文件夹中。如果这样做,您不需要额外的配置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接