簡體   English   中英

將自定義命令行 arguments 傳遞給 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' and cargo test -- --help顯示它有一組固定的選項

Usage: --help [OPTIONS] [FILTER]

Options:
        --include-ignored 
                        Run ignored and not ignored tests
        --ignored       Run only ignored tests
...

我的另一個想法是在環境變量中傳遞 arguments,即

DOCTEST_ARGS="--test-case='X'" cargo test

但隨后我需要在 Rust 或 C++ 中以某種方式將該字符串拆分為 arguments(至少正確處理空格和引號)。

運行cargo test時,涉及到兩條Rust 工具鏈。

cargo test本身在 package 或工作區中查找所有可測試目標,使用cfg(test)構建它們,並運行這些二進制文件。 cargo test處理--左側的 arguments ,右側的 arguments 傳遞給二進制文件。

然后,

測試是使用rustc--test選項構建的,該選項創建一個帶有main function 的可執行文件,該文件在多個線程中自動運行所有使用 #[test] 屬性注釋的函數。 #[bench]帶注釋的函數也將運行一次迭代以驗證它們是否正常工作。

libtest 工具可以通過在目標清單設置中設置harness = false來禁用,在這種情況下,您的代碼將需要提供自己的main function 來處理運行測試。

“libtest 工具”拒絕了你額外的 arguments。 就您而言,由於您打算運行整個其他測試套件,因此我認為禁用該工具是合適的。

  1. 將您的委托代碼移動到它自己的文件中,通常位於您的 package 目錄中的tests/中:

     Cargo.toml src/ lib.rs... tests/ cpp_test.rs
  2. Cargo.toml中為它寫一個明確的目標部分,禁用線束:

     [[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
  3. cpp_test.rs中,不要編寫帶有#[test]屬性的 function ,而是編寫一個普通的main function ,它讀取env::args()並調用 ZF6F87C9FDCF1B3C3F09ZF93 測試。

[免責聲明:我熟悉這些機制,因為我使用了 Criterion 基准測試(同樣需要禁用默認線束),但我實際上並沒有按照您正在尋找的方式使用自定義 arguments 編寫測試。 所以,有些細節可能是錯誤的。 如果有任何需要糾正的地方,請告訴我。]

除了Kevin Reid 的回答之外,如果您不想編寫自己的測試工具,可以使用shell-words crate將環境變量拆分為單獨的 arguments 遵循 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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM