rust怎麼關陽光指令 Rust入坑指南 步步為營

2021-10-13 08:49:47 字數 3928 閱讀 6340

俗話說:「測試寫得好,獎金少不了。」

寫單元測試一般需要三個步驟:

準備測試用例,測試用例要能覆蓋盡可能多的**

執行需要測試的**

判斷結果,是否是你希望得到的結果

了解了這些以後,我們就來看看在rust中應該怎麼寫單元測試。

首先我們建立乙個library專案

$ cargo new adder --lib

created library `adder` project

然後在src/lib.rs檔案中開始寫測試**

#[cfg(test)]

mod tests {

#[test]

fn it_works() {

assert_eq!(2 + 2, 4);

此時在命令列執行cargo test就會得到測試結果

可以看到,結果顯示,rust執行了一項測試並且測試通過。後面的doc-tests我們先放下,以後再聊。

當然,這並不是我們常見的測試,在日常開發中,我們通常是先寫我們的業務**然後再對各個函式進行單元測試,最後還會對某個模組進行整合測試。那麼我們就來模擬一下日常開發過程中應該如何來寫測試。

單元測試

我們仍然是用上面的專案,先來在src/lib.rs中寫一段「業務**」

pub fn add_two(a: i32) -> i32 {

internal_adder(a, 2)

fn internal_adder(a: i32, b: i32) -> i32 {

a + b

這是一段非常簡單的**,對外暴露的函式只是乙個加2的功能,內部呼叫了乙個兩數相加的函式。現在我們就對這個內部函式做乙個單元測試。

#[cfg(test)]

mod tests {

use super::*;

#[test]

fn internal() {

assert_eq!(4, internal_adder(2, 2));

在測試模組中,如果想要使用我們業務**中的函式,就需要通過use super::*;將其引入可用範圍。接著,還是執行cargo test,測試結果與剛才類似。

測了半天全是通過的沒什麼意思,單元測試真正的作用是要發現**中的問題,所以我們來嘗試乙個錯誤的試一下。假設我們希望2+2等於5。

rust就會將錯誤棧列印出來,根據結果提示,這並不是完整的錯誤棧,我們還可以將rust_backtrace設定為full來檢視更加詳細的資訊。這裡我就不做演示了。

整合測試

接下來我們再演示一下整合測試。我們通常將整合測試單獨放到乙個目錄中,在lib.rs檔案中,rust識別測試mod的名稱是tests,同樣的,我們在src下建立tests目錄。tests目錄下就是我們的所有整合測試**。

如圖,integration_test是我們測試**的檔案,common目錄下的mod.rs檔案中是一些整合測試必要的配置。這裡我們只是放了乙個空的setup函式。

在整合測試中,我們就要像正常他人使用我們的**時那樣來進行測試,首先需要將我們的mod引入到可用範圍,當然還需要加上common的mod。

use adder;

mod common;

#[tests]

fn it_adds_two() {

common::setup();

assert_eq!(4, adder::add_two(2));

接著就可以測試我們對外暴露的函式了。

ok,整合測試的方法我們也掌握了。現在來看看一直被我們忽略的doc-tests吧。

文件測試

我們已經知道,rust中的注釋是雙斜線//,像我們剛剛寫的library**,如果想要把它發布到crate.io上讓別人使用,那麼我們就需要增加相應的文件,這裡文件的每行都應該是三斜線///開頭,而文件中也應該放一些例子供他人參考。

/// adds two to the number given.

/// # examples

/// let arg = 5;

/// let answer = adder::add_two(arg);

/// assert_eq!(7, answer);

pub fn add_two(a: i32) -> i32 {

internal_adder(a, 2)

現在我給add_two函式加上了文件,我們再次執行cargo test命令。

現在我們就明白了,doc-tests測試就是執行我們文件中的例子。

常用特性

到目前為止,我們已經知道了在rust中如何寫測試**了。接下來我們再來了解幾個比較常用的特性。

執行指定的測試**

我們在開發過程中肯定不會每次都去跑全量的單元測試,那樣太浪費時間了。通常是我們開發完乙個功能之後,編寫對應的單元測試,然後單獨跑這個測試。那麼rust中能不能單獨跑乙個單元測試呢?答案是肯定的。

相信細心的同學已經發現了,rust測試結果中,是針對每個測試單獨統計結果,並且每個測試都有自己的名字,像我們前面寫的it_works和internal。假設我們的**中同時存在這兩個函式,如果你想要單獨跑internal這乙個測試,就可以使用cargo test internal命令。

你也可以使用這種方法來執行多個名稱類似的測試,假如我們有名稱為internal_a的測試,那麼執行cargo test internal命令時它也會被執行。

忽略某個測試

當我們有乙個測試執行時間非常長的時候,我們一般不會輕易去執行,這時如果你想要執行多個測試,除了用我們上面提到的方法,去指定不同的名稱列表以外。還可以把這個測試忽略掉。

現在我不想執行internal測試了,只需要對**進行如下改動:

#[test]

#[ignore]

fn internal() {

assert_eq!(4, internal_adder(2, 2));

這時再來執行測試,結果如圖所示。

我們發現此時internal測試已經被忽略了。

測試異常情況

除了測試**邏輯正常的情況,我們有時還需要測試一些異常情況,比如接收到非法引數時程式能否返回我們希望看到的異常。

我們首先來看一下如何測試程式返回異常資訊。

rust為我們提供了乙個叫做should_panic的註解。我們可以使用它來測試程式是否返回異常:

pub fn add_two(a: i32) -> i32 {

internal_adder(a, 2)

fn internal_adder(a: i32, b: i32) -> i32 {

if a < 0 {

panic!("a should bigger than 0");

a + b

#[cfg(test)]

mod tests {

use super::*;

#[test]

#[should_panic]

fn internal() {

assert_eq!(4, internal_adder(-2, 2));

此時我們執行測試時就會發現internal測試通過,因為它發生了執行緒恐慌,這是我們希望看到的結果。

另外,我們還可以再指定我們具體期望的異常,那麼就可以在should_panic後面加上expected引數。

#[test]

#[should_panic(expected = "a should be positive")]

fn internal() {

assert_eq!(4, internal_adder(-2, 2));

大家可以自行執行一下這段測試**看看效果。

總結文中我向大家介紹了在rust中如何進行單元測試、整合測試,還有比較特殊的文件測試。最後還介紹了3種常見的測試特性。

最後想友情提醒大家一下,在開發過程中,不要寫完一堆功能後再開始寫單元測試,這時你很有可能會因為測試**過於繁瑣而放棄。建議大家每寫乙個功能,隨即開始進行單元測試,這樣也能立即看到自己的**的執行效果,提高成就感。這就是所謂的「步步為營」。,

rust怎麼拆除牆壁指令 朝陽粉碎拆除費用

朝陽粉碎拆除費用,北京億順達建築工程 憑藉這兩項優勢,在激烈的行業競爭中贏得多次承包和分包合作機會,並贏得客戶的一致好評。朝陽粉碎拆除費用,您的資訊將被嚴格保密!地面見底位置一定要先做好防水,不然在施工過程中很有可能會把水滲到樓下,避免給自己帶來不必要的麻煩。對清潔和排水沒有影響的情況下,馬桶可以最...

rust儲物箱怎麼帶走 Rust Rc 方法整理

ref alloc rc rc rust 方法new pintry unwrap into raw from raw downgrade weak count strong count get mut ptr eq make mut downcast std rc rc 是單執行緒引用計數指標。rc...

rust腐蝕 木製窗戶怎麼修 白蟻是怎麼來的?

白蟻作為三大社會性昆蟲之一,與蟑螂是近親。屬蜚蠊目,簡稱螱,英文為oe white ants。分布熱帶和溫帶,目前世界已知3000多種。我國已知白蟻4科近500種成蟲體小至中型,體壁柔弱,多型性。工蟻白色,頭常為圓形或長形,口器咀嚼式,觸角長,念珠狀,無翅 兵蟻類似工蟻,但頭較大,上顎發達 繁殖蟻有...