将自定义命令行参数传递给 Rust 测试
Passing custom command-line arguments to a Rust test
我有一个 Rust 测试,它使用 doctest 委托给 C++ 测试套件,并想将命令行参数传递给它。我的第一次尝试是
// in mod ffi
pub fn run_tests(cli_args: &mut [String]) -> bool;
#[test]
fn run_cpp_test_suite() {
let mut cli_args: Vec<String> = env::args().collect();
if !ffi::run_tests(
cli_args.as_mut_slice(),
) {
panic!("C++ test suite reported errors");
}
}
因为cargo test help
显示
USAGE:
cargo.exe test [OPTIONS] [TESTNAME] [-- <args>...]
我预计
cargo test -- --test-case="X"
让run_cpp_test_suite
访问并传递--test-case="X"
参数。但事实并非如此;我得到 error: Unrecognized option: 'test-case'
和 cargo test -- --help
表明它有一组固定的选项
Usage: --help [OPTIONS] [FILTER]
Options:
--include-ignored
Run ignored and not ignored tests
--ignored Run only ignored tests
...
我的另一个想法是在环境变量中传递参数,即
DOCTEST_ARGS="--test-case='X'" cargo test
但是我需要以某种方式将该字符串拆分为 Rust 或 C++ 中的参数(至少正确处理空格和引号)。
涉及两个个Rust工具链when you run cargo test
。
cargo test
本身会在您的包或工作区中查找所有可测试的目标,使用 cfg(test)
构建它们,然后 运行 那些二进制文件。 cargo test
处理 --
左边的参数,右边的参数传递给二进制文件。
然后,
Tests are built with the --test
option to rustc
which creates an executable with a main
function that automatically runs all functions annotated with the #[test] attribute in multiple threads. #[bench]
annotated functions will also be run with one iteration to verify that they are functional.
The libtest harness may be disabled by setting harness = false
in the target manifest settings, in which case your code will need to provide its own main
function to handle running tests.
“libtest harness”拒绝了您的额外论点。在您的情况下,由于您打算 运行 整个其他测试套件,我认为禁用线束是合适的。
将您的委托代码移动到它自己的文件中,通常位于包目录中的 tests/
:
Cargo.toml
src/
lib.rs
...
tests/
cpp_test.rs
在你的Cargo.toml
中为它写一个明确的target section,禁用线束:
[[test]]
name = "cpp_test"
# path = "tests/cpp_test.rs" # This is automatic; you can use a different path if you really want to.
harness = false
在 cpp_test.rs
中,不是编写带有 #[test]
属性的函数,而是编写一个普通的 main
函数,该函数读取 env::args()
并调用C++ 测试。
[免责声明:我熟悉这些机制,因为我使用了 Criterion 基准测试(同样需要禁用默认工具),但我实际上并没有按照您正在寻找的方式编写带有自定义参数的测试.所以,有些细节可能是错误的。如果有任何需要更正的地方,请告诉我。]
除了 , if you don't want to write your own test harness, you can use the shell-words
crate 按照 shell 规则将环境变量拆分为单独的参数外:
let args = var ("DOCTEST_ARGS").unwrap_or_else (|_| String::new());
let args = shell_words::split (&args).expect ("failed to parse DOCTEST_ARGS");
Command::new ("cpptest")
.args (args)
.spawn()
.expect ("failed to start subprocess")
.wait()
.expect ("failed to wait for subprocess");
我有一个 Rust 测试,它使用 doctest 委托给 C++ 测试套件,并想将命令行参数传递给它。我的第一次尝试是
// in mod ffi
pub fn run_tests(cli_args: &mut [String]) -> bool;
#[test]
fn run_cpp_test_suite() {
let mut cli_args: Vec<String> = env::args().collect();
if !ffi::run_tests(
cli_args.as_mut_slice(),
) {
panic!("C++ test suite reported errors");
}
}
因为cargo test help
显示
USAGE:
cargo.exe test [OPTIONS] [TESTNAME] [-- <args>...]
我预计
cargo test -- --test-case="X"
让run_cpp_test_suite
访问并传递--test-case="X"
参数。但事实并非如此;我得到 error: Unrecognized option: 'test-case'
和 cargo test -- --help
表明它有一组固定的选项
Usage: --help [OPTIONS] [FILTER]
Options:
--include-ignored
Run ignored and not ignored tests
--ignored Run only ignored tests
...
我的另一个想法是在环境变量中传递参数,即
DOCTEST_ARGS="--test-case='X'" cargo test
但是我需要以某种方式将该字符串拆分为 Rust 或 C++ 中的参数(至少正确处理空格和引号)。
涉及两个个Rust工具链when you run cargo test
。
cargo test
本身会在您的包或工作区中查找所有可测试的目标,使用 cfg(test)
构建它们,然后 运行 那些二进制文件。 cargo test
处理 --
左边的参数,右边的参数传递给二进制文件。
然后,
Tests are built with the
--test
option torustc
which creates an executable with amain
function that automatically runs all functions annotated with the #[test] attribute in multiple threads.#[bench]
annotated functions will also be run with one iteration to verify that they are functional.The libtest harness may be disabled by setting
harness = false
in the target manifest settings, in which case your code will need to provide its ownmain
function to handle running tests.
“libtest harness”拒绝了您的额外论点。在您的情况下,由于您打算 运行 整个其他测试套件,我认为禁用线束是合适的。
将您的委托代码移动到它自己的文件中,通常位于包目录中的
tests/
:Cargo.toml src/ lib.rs ... tests/ cpp_test.rs
在你的
Cargo.toml
中为它写一个明确的target section,禁用线束:[[test]] name = "cpp_test" # path = "tests/cpp_test.rs" # This is automatic; you can use a different path if you really want to. harness = false
在
cpp_test.rs
中,不是编写带有#[test]
属性的函数,而是编写一个普通的main
函数,该函数读取env::args()
并调用C++ 测试。
[免责声明:我熟悉这些机制,因为我使用了 Criterion 基准测试(同样需要禁用默认工具),但我实际上并没有按照您正在寻找的方式编写带有自定义参数的测试.所以,有些细节可能是错误的。如果有任何需要更正的地方,请告诉我。]
除了 shell-words
crate 按照 shell 规则将环境变量拆分为单独的参数外:
let args = var ("DOCTEST_ARGS").unwrap_or_else (|_| String::new());
let args = shell_words::split (&args).expect ("failed to parse DOCTEST_ARGS");
Command::new ("cpptest")
.args (args)
.spawn()
.expect ("failed to start subprocess")
.wait()
.expect ("failed to wait for subprocess");