簡體   English   中英

如何將測試移動到 Rust 的 Cargo 二進制文件的單獨文件中?

[英]How to move tests into a separate file for binaries in Rust's Cargo?

我使用 Cargo 創建了一個新的二進制文件:

cargo new my_binary --bin

my_binary/src/main.rs中的一個function可以用來測試:

fn function_from_main() {
    println!("Test OK");
}

#[test]
fn my_test() {
    function_from_main();
}

並且cargo test -- --nocapture按預期運行測試。

將此測試移至單獨文件的最直接方法是什么(將function_from_main保留在my_binary/src/main.rs中)?

我試圖這樣做但不確定如何從單獨的文件中調用function_from_main my_test

Rust 編程語言一章專門介紹測試,你應該閱讀它以獲得基本的理解。


將單元測試(允許訪問代碼內部的test )放入每個特定文件的test模塊中是很常見的:

fn function_from_main() {
    println!("Test OK");
}

#[cfg(test)]
mod test {
    use super::*;
    
    #[test]
    fn my_test() {
        function_from_main();
    }
}

模塊可以移動到新文件,盡管這對於單元測試模塊來說並不常見:

主文件

fn function_from_main() {
    println!("Test OK");
}

#[cfg(test)]
mod test;

測試.rs

use super::*;

#[test]
fn my_test() {
    function_from_main();
}

有關文件和模塊如何相互映射的詳細信息,請參閱將模塊分成不同的文件


單獨文件中的測試更常見的情況是集成測試。 書中還有一個專門介紹板條箱外測試部分 這些類型的測試非常適合作為代碼的使用者來執行代碼

文檔的該部分包括介紹性示例和描述性文本:

我們在項目目錄的頂層創建一個測試目錄,在src旁邊。 Cargo 知道在這個目錄中尋找集成測試文件。 然后我們可以在這個目錄中創建任意數量的測試文件,Cargo 會將每個文件編譯為一個單獨的 crate。

讓我們創建一個集成測試。 示例11-12 中的代碼仍在src/lib.rs文件中,創建一個測試目錄,創建一個名為tests/integration_test.rs的新文件,然后輸入示例11-13 中的代碼:

文件名:tests/integration_test.rs

 use adder; #[test] fn it_adds_two() { assert_eq!(4, adder::add_two(2)); }

示例 11-13:加法器箱中函數的集成測試

我們在代碼頂部添加了use adder ,我們在單元測試中不需要它。 原因是 tests 目錄中的每個測試都是一個單獨的 crate,所以我們需要將我們的庫放入每個 test crate 的范圍內。

請注意,該函數被稱為adder::add_two 關於 Rust 模塊系統的更多細節可以在包、板條箱和模塊章節中找到

由於這些測試像用戶一樣運行您的 crate,如果您想測試一個binary ,您應該執行 binary assert_cmd這樣的crate可以幫助減少這種類型的測試的痛苦。

在其他情況下,您應該將大二進制文件分解為一個大庫和一個小二進制文件。 然后,您可以為庫的公共 API 編寫集成測試。

另見:

如果你有一個模塊foo.rs並且想要將你的單元測試放在一個名為foo_test.rs的文件中,你會發現這並不總是 Rust 尋找子模塊的地方。

可以使用#[path]屬性指定模塊對應的文件位置:

#[cfg(test)]
#[path = "./foo_test.rs"]
mod foo_test;

這在博客文章Better location for unit tests in Rust 中進行了解釋

你說得對; function_from_mainmain.rs之外是不可訪問的。

您需要創建一個src/lib.rssrc/lib.rs移動要測試的函數。 然后你就可以使用extern crate my_binary; 來自您的測試模塊,並使您的函數出現在my_binary命名空間下。

我確實相信您應該遵循閱讀 Rust 書中測試章節的建議,但是,這仍然不能完全回答您的問題,如何分離測試文件和源文件

假設您有一個lib.rs源文件並想要一個test_lib.rs文件。 為此,您只需要:

在你的lib.rs

mod test_lib;

// rest of source

然后在你的test_lib.rs中:

#[cfg(test)]
use super::*;

#[test]
fn test1() {
    // test logic 
}

// more tests

然后,你和cargo test應該都很開心。

修飾*@mmai 的回答:

#[rustfmt::skip]
#[cfg(test)]
#[path = "./foo_test.rs"]
mod foo_test;

cargo fmt似乎對新測試文件的路徑不滿意。 如果有人有更好的解決方案,我會很高興聽到它,因為我希望cargo fmt也能格式化我的測試文件!

*抱歉:我添加這個只是作為對現有答案的評論,但我沒有足夠的聲譽。

暫無
暫無

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

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