<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                > Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence. > > Edsger W. Dijkstra, "The Humble Programmer" (1972) > > 軟件測試是證明bug存在的有效方法,而證明它們不存在時則顯得令人絕望的不足。 > > Edsger W. Dijkstra,【謙卑的程序員】(1972) 讓我們討論一下如何測試Rust代碼。在這里我們不會討論什么是測試Rust代碼的正確方法。這里有很多關于寫測試好壞方法的流派。所有的這些途徑都使用相同的基本工具,所以我們會想你展示他們的語法。 ## `測試`屬性(The test attribute) 簡單的說,測試是一個標記為`test`屬性的函數。讓我們用Cargo來創建一個叫`adder`的項目: ~~~ $ cargo new adder $ cd adder ~~~ 在你創建一個新項目時Cargo會自動生成一個簡單的測試。下面是`src/lib.rs`的內容: ~~~ #[test] fn it_works() { } ~~~ 注意這個`#[test]`。這個屬性表明這是一個測試函數。它現在沒有函數體。它肯定能編譯通過!讓我們用`cargo test`運行測試: ~~~ $ cargo test Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ~~~ Cargo編譯和運行了我們的測試。這里有兩部分輸出:一個是我們寫的測試,另一個是文檔測試。我們稍后再討論這些。現在,看看這行: ~~~ test it_works ... ok ~~~ 注意那個`it_works`。這是我們函數的名字: ~~~ fn it_works() { ~~~ 然后我們有一個總結行: ~~~ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured ~~~ 那么為啥我們這個啥都沒干的測試通過了呢?任何沒有`panic!`的測試通過,`panic!`的測試失敗。讓我們的測試失敗: ~~~ #[test] fn it_works() { assert!(false); } ~~~ `assert!`是Rust提供的一個宏,它接受一個參數:如果參數是`true`,啥也不會發生。如果參數是`false`,它會`panic!`。讓我們再次運行我們的測試: ~~~ $ cargo test Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test it_works ... FAILED failures: ---- it_works stdout ---- thread 'it_works' panicked at 'assertion failed: false', /home/steve/tmp/adder/src/lib.rs:3 failures: it_works test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured thread '<main>' panicked at 'Some tests failed', /home/steve/src/rust/src/libtest/lib.rs:247 ~~~ Rust指出我們的測試失敗了: ~~~ test it_works ... FAILED ~~~ 這反映在了總結行上: ~~~ test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured ~~~ 我們也得到了一個非0的狀態值: ~~~ $ echo $? 101 ~~~ 這在你想把`cargo test`集成進其它工具是非常有用。 我們可以使用另一個屬性反轉我們的失敗的測試:`should_panic`: ~~~ #[test] #[should_panic] fn it_works() { assert!(false); } ~~~ 現在即使我們`panic!`了測試也會通過,并且如果我們的測試通過了則會失敗。讓我試一下: ~~~ $ cargo test Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ~~~ Rust提供了另一個宏,`assert_eq!`用來比較兩個參數: ~~~ #[test] #[should_panic] fn it_works() { assert_eq!("Hello", "world"); } ~~~ 那個測試通過了嗎?因為那個`should_panic`屬性,它通過了: ~~~ $ cargo test Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ~~~ `should_panic`測試是脆弱的,因為很難保證測試是否會因什么不可預測原因并未失敗。為了解決這個問題,`should_panic`屬性可以添加一個可選的`expected`參數。這個參數可以確保失敗信息中包含我們提供的文字。下面是我們例子的一個更安全的版本: ~~~ #[test] #[should_panic(expected = "assertion failed")] fn it_works() { assert_eq!("Hello", "world"); } ~~~ 這就是全部的基礎內容!讓我們寫一個“真實”的測試: ~~~ pub fn add_two(a: i32) -> i32 { a + 2 } #[test] fn it_works() { assert_eq!(4, add_two(2)); } ~~~ `assert_eq!`是非常常見的;用已知的參數調用一些函數然后與期望的輸出進行比較。 # `tests`模塊 這有一個問題令我們當前的項目并不理想:它缺少`tests`模塊。我們例子的理想寫法如下: ~~~ pub fn add_two(a: i32) -> i32 { a + 2 } #[cfg(test)] mod tests { use super::add_two; #[test] fn it_works() { assert_eq!(4, add_two(2)); } } ~~~ 這里產生了一些變化。第一個變化是引入了一個`cfg`屬性的`mod tests`。這個模塊允許我們把所有測試集中到一起,并且需要的話還可以定義輔助函數,它們不會成為我們包裝箱的一部分。`cfg`屬性只會在我們嘗試去運行測試時才會編譯測試代碼。這樣可以節省編譯時間,并且也確保我們的測試代碼完全不會出現在我們的正式構建中。 第二個變化是`use`聲明。因為我們在一個內部模塊中,我們需要把我們要測試的函數導入到當前空間中。如果你有一個大型模塊的話這會非常煩人,所以這里有經常使用一個`glob`功能。讓我們修改我們的`src/lib.rs`來使用這個: ~~~ pub fn add_two(a: i32) -> i32 { a + 2 } #[cfg(test)] mod tests { use super::*; #[test] fn it_works() { assert_eq!(4, add_two(2)); } } ~~~ 注意`use`行的變化。現在運行我們的測試: ~~~ $ cargo test Updating registry `https://github.com/rust-lang/crates.io-index` Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test test::it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ~~~ 目前的習慣是使用`test`模塊來存放你的“單元測試”。任何只是測試一小部分功能的測試理應放在這里。那么“集成測試”怎么辦呢?我們有`tests`目錄來處理這些。 ## `tests`目錄 為了進行集成測試,讓我們創建一個`tests`目錄,然后放一個`tests/lib.rs`文件進去,輸入如下內容: ~~~ extern crate adder; #[test] fn it_works() { assert_eq!(4, adder::add_two(2)); } ~~~ 這看起來與我們剛才的測試很像,不過有些許的不同。我們現在有一行`extern crate adder`在開頭。這是因為在`tests`目錄中的測試另一個完全不同的包裝箱,所以我們需要導入我們的庫。這也是為什么`tests`是一個寫集成測試的好地方:它們就想其它程序一樣使用我們的庫。 讓我們運行一下: ~~~ $ cargo test Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test test::it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Running target/lib-c18e7d3494509e74 running 1 test test it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ~~~ 現在我們有了三個部分:我們之前的兩個測試,然后還有我們新添加的。 這就是`tests`目錄的全部內容。它不需要`test`模塊因為它整個就是關于測試的。 讓我們最后看看第三部分:文檔測試。 ## 文檔測試 沒有什么是比帶有例子的文檔更好的了。當然也沒有什么比不能工作的例子更糟的,因為文檔完成之后代碼已經被改寫。為此,Rust支持自動運行你文檔中的例子。這是一個完整的有例子的`src/lib.rs`: ~~~ //! The `adder` crate provides functions that add numbers to other numbers. //! //! # Examples //! //! ` ` ` 因為gitbook排版問題,這里多寫了兩個空格 //! assert_eq!(4, adder::add_two(2)); //! ` ` ` 因為gitbook排版問題,這里多寫了兩個空格 /// This function adds two to its argument. /// /// # Examples /// /// ` ` ` 因為gitbook排版問題,這里多寫了兩個空格 /// use adder::add_two; /// /// assert_eq!(4, add_two(2)); /// ` ` ` 因為gitbook排版問題,這里多寫了兩個空格 pub fn add_two(a: i32) -> i32 { a + 2 } #[cfg(test)] mod tests { use super::*; #[test] fn it_works() { assert_eq!(4, add_two(2)); } } ~~~ 注意模塊級的文檔以`//!`開頭然后函數級的文檔以`///`開頭。Rust文檔在注釋中支持Markdown語法,所以它支持3個反單引號代碼塊語法。想上面例子那樣,加入一個`# Examples`部分被認為是一個慣例。 讓我們再次運行測試: ~~~ $ cargo test Compiling adder v0.0.1 (file:///home/steve/tmp/adder) Running target/adder-91b3e234d4ed382a running 1 test test test::it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Running target/lib-c18e7d3494509e74 running 1 test test it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 2 tests test add_two_0 ... ok test _0 ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured ~~~ 現在我們運行了3種測試!注意文檔測試的名稱:`_0`生成為模塊測試,而`add_two_0`函數測試。如果你添加更多用例的話它們會像`add_two_1`這樣自動加一。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看